Ich habe ein Problem zu prüfen, ob ein bestimmter Befehl in einer Befehlskette Multi-Rohr hat einen Fehler aus. Normalerweise ist das nicht schwer zu überprüfen, aber weder set -o pipefail
noch Überprüfung ${PIPESTATUS[@]}
funktioniert in meinem Fall. Das Setup ist wie folgt:Bash: Prüfung auf Exit-Status von Multi-Rohrbefehlskette
Hinweis-1: Der Befehl wurde gründlich getestet und funktioniert einwandfrei.
Jetzt will ich in einem Array die Ausgabe dieses Befehls speichern procdata
genannt. So, ich habe:
declare -a procdata
procdata=($(eval $cmd))
Hinweis-2: eval
ist notwendig, weil sonst $snmpcmd
mit einem invalid option -- <grepoption>
Fehler wirft, die keinen Sinn macht, weil <grepoption>
offensichtlich keine $snmpcmd
Option. In diesem Stadium halte ich dies einen Fehler mit $snmpcmd
, aber das ist eine andere Show ...
Wenn ein Fehler auftritt, wird procdata
leer sein. Allerdings könnte es aus zwei verschiedenen Gründen leer sein: entweder, weil ein Fehler aufgetreten ist, während die Ausführung $snmpcmd
(z Timeout) oder weil grep
konnte nicht finden, was sie suchte. Das Problem ist, ich muss in der Lage sein, zwischen diesen beiden Fällen unterscheiden und sie getrennt behandeln.
Daher ist set -o pipefail
keine Option, da es einen Fehler propagieren wird und ich kann nicht unterscheiden, welcher Teil der Pipe fehlgeschlagen ist. Auf der anderen Seite echo ${PIPESTATUS[@]}
ist immer 0
nach procdata=($(eval $cmd))
obwohl ich viele Rohre habe!?. Wenn ich jedoch den gesamten Befehl direkt an der Eingabeaufforderung ausführe und unmittelbar danach echo ${PIPESTATUS[@]}
aufruft, wird der Exit-Status aller Pipes korrekt zurückgegeben.
Ich weiß, ich könnte den Err-Stream an stdout binden, aber ich müsste heuristische Methoden verwenden, um zu überprüfen, ob die Elemente in procdata
gültig sind oder Fehlermeldungen und ich riskiere falsch positive Ergebnisse. Ich könnte auch stdout auf /dev/null
pipen und nur den Fehlerstrom erfassen und überprüfen, ob ${#procdata[@]} -eq 0
. Aber ich müsste den Aufruf wiederholen, um die tatsächlichen Daten zu erhalten, und das ganze Kommando ist zeitaufwändig (ca. 3-5s). Ich würde es nicht zweimal anrufen wollen. Oder ich könnte eine temporäre Datei verwenden, um Fehler zu schreiben, aber ich würde es lieber ohne den Aufwand machen, Dateien zu erstellen/löschen.
Irgendwelche Ideen, wie ich diese Arbeit in bash machen?
Dank
PS:
$ echo $BASH_VERSION
4.2.37(1)-release
ich den gleichen Gedanken hatte. Leider funktioniert es auch nicht, aber ich bin mir nicht sicher warum. Ich poste die genauen Befehle, weil ich das Offensichtliche nicht sehen könnte: – user3040975
'local cmdargs =" - CHf, -m $ mibs -v $ snmp-c $ community $ agent "; local procdatacmd = "$ tblcmd $ cmdargs $ proc_table"; procdatacmd + = "| cut -d ',' -f $ Felder | grep -we -e | sort | uniq -c | sed 's/^ * \ | \" // g; s//,/g' ; echo $ {PIPESTATUS [@]} ". Dann tue ich:' deklariere -a procdata = ($ (head -n -1 <<< $ procdatacmd)) '. Die Ausgabe ist leer ... einfach nichts. und läuft und läuft auf dem Agenten. Was die ... –
user3040975
@ user3040975 Sie scheinen nicht _running_ einen Befehl in der Zeile oben zu sein. – devnull