Pipes und Returncodes in ksh
Orginal Lösung gefunden auf: aremark.concept-in.org/2009/01/capture-piped-command-status-in-ksh.html
Problem: Beim duplizieren der Standardausgabe mit tee ist der Returncode
von tee und nicht vom dem Kommando vor der Pipe.
Hier ein Ansatz um den Returncode vor der Pipe zu speichern.
1. duplizieren der Standardausgabe
# exec 3>&1
2. ein kleines Skript zum testen
# cat z.sh echo returncode 127 exit 127 # chmod 700 z.sh
3. Jetzt kommt es:
# status=$( ( (./z.sh 2>&1; echo $? >&4 ) |tee z.log >&3 ) 4>&1 )
status -> Variable in der der Returncode gespeichert werden soll.
Ich interpretiere die Zeile jetzt von innen nach außen.
4. ./z.sh 2>&1; echo $? >&4
Das Skript z.sh gibt die Zeile // echo returncode 127 // auf der Standardausgabe aus.
Es beendet sich mit dem Returncode 127. Der Returncode wird abgefragt // echo $? // ,
aber nicht auf der Standardausgabe ausgegeben, sondern im Filedescriptor 4 gespeichert.
Wir erinnern uns ;-) // echo returncode 127 // wird auf der Standardausgabe ausgegeben und
somit in die Pipe geschickt.
5. tee z.log >&3
Jetzt ist das tee am Zuge. Das tee liest aus der Pipe den string // returncode 127 //, schreibt es
in die Logdatei z.log und gibt es gleichzeitig auf der Standardausgabe aus. Diese wird
umgeleitet // >&3 // zum Filedescriptor 3. Siehe Punkt 1.
6. 4>&1
Als letztes wird der Buffer des Filedescriptors 4 auf die Standardausgabe geschrieben
(da steht unser Returncode von vor der Pipe drin) und landet somit in der Variable // status //
Der Status kann mit einem
# echo $status
angezeigt werden.
Und jetzt das ganze in einem Ruck:
# exec 3>&1 # status=$( ( (./z.sh 2>&1; echo $? >&4 ) |tee z.log >&3 ) 4>&1 ) # echo $status