Bash: Überprüfen der exit-status des multi-pipe-Kommando-Kette

Ich habe ein problem, die Prüfung, ob ein bestimmter Befehl in einem multi-pipe-Befehl Kette hat einen Fehler auslösen. In der Regel ist dies nicht schwer zu überprüfen, aber weder set -o pipefail noch durch ${PIPESTATUS[@]} funktioniert in meinem Fall. Das setup ist wie folgt:

cmd="$snmpcmd $snmpargs $agent $oid | grep <grepoptions> for_stuff | cut -d',' f$fields | sed 's/ubstitute/some_other_stuff/g'"

Hinweis-1: Der Befehl wurde gründlich getestet und funktioniert einwandfrei.

Jetzt, ich möchten, speichern Sie die Ausgabe des Befehls in ein array mit dem Namen procdata. Also, ich habe:

declare -a procdata
procdata=( $(eval $cmd) )

Hinweis-2: eval ist notwendig, weil sonst $snmpcmd wirft mit einem invalid option -- <grepoption> Fehler, die keinen Sinn macht, weil <grepoption> ist nicht ein $snmpcmd option offensichtlich. In diesem Stadium halte ich das ein Fehler bei $snmpcmd aber das ist eine andere show...

Wenn ein Fehler verwickelt, procdata leer. Es könnte aber auch leer sein, für zwei verschiedene Ursachen haben: entweder da ist ein Fehler aufgetreten während der Ausführung der $snmpcmd (z.B. timeout), oder weil grep konnte nicht finden, was es suchte. Das problem ist, ich muss in der Lage sein, zu unterscheiden zwischen diesen beiden Fällen und diese separat behandeln.

So set -o pipefail ist keine option, da es zu propagieren, die alle Fehler und ich kann nicht unterscheiden, welcher Teil der pipe ist fehlgeschlagen. Auf der anderen Seite echo ${PIPESTATUS[@]} ist immer 0 nach procdata=( $(eval $cmd) ) obwohl ich viele Rohre!?. Doch wenn ich die ausführen den ganzen Befehl direkt an der Eingabeaufforderung, und rufen Sie echo ${PIPESTATUS[@]} sofort nach, es gibt den exit-status aller Leitungen korrekt.

Ich weiß, ich könnte binden die err-stream auf stdout aus, aber ich hätte zu verwenden heuristische Methoden, um zu überprüfen, ob die Elemente in procdata gültig sind oder Fehlermeldungen und ich laufen das Risiko von false positives. Ich könnte auch pipe stdout zu /dev/null und erfassen nur den error-stream und überprüfen Sie, ob ${#procdata[@]} -eq 0. Aber ich würde wiederholen Sie den Anruf, um die tatsächlichen Daten, und der ganze Befehl ist an der Zeit teuer (ca. 3-5s). Ich würde nicht wollen, nennen Sie es zweimal. Oder könnte ich eine temporäre Datei zu schreiben, die Fehler, aber ich würde lieber tun Sie es, ohne den overhead für das erzeugen/löschen von Dateien.

Irgendwelche Ideen, wie ich kann machen diese Arbeit in der bash?

Dank

P. S.:

$ echo $BASH_VERSION
4.2.37(1)-release
InformationsquelleAutor user3040975 | 2013-12-13
Schreibe einen Kommentar