Der Ausgangsstatus einer Pipe ist der Ausgangsstatus des rechten Befehls. Der Exit-Status des linken Befehls wird ignoriert.
(Beachten Sie, dass which lss | echo $?
dies nicht angezeigt wird. Sie würden es ausführen which lss | true; echo $?
, um dies anzuzeigen. In which lss | echo $?
gibt echo $?
den Status des letzten Befehls vor dieser Pipeline an.)
Der Grund, warum sich Shells so verhalten, ist, dass es ein ziemlich häufiges Szenario gibt, in dem ein Fehler auf der linken Seite ignoriert werden sollte. Wenn die rechte Seite beendet wird (oder im Allgemeinen ihre Standardeingabe schließt), während die linke Seite noch schreibt, empfängt die linke Seite ein SIGPIPE-Signal. In diesem Fall ist normalerweise nichts falsch: Die rechte Seite kümmert sich nicht um die Daten; Wenn die Rolle der linken Seite ausschließlich darin besteht, diese Daten zu erzeugen, kann sie gestoppt werden.
Wenn jedoch die linke Seite aus einem anderen Grund als SIGPIPE stirbt oder wenn die Aufgabe der linken Seite nicht nur darin bestand, Daten zur Standardausgabe zu erzeugen, ist ein Fehler auf der linken Seite ein echter Fehler sollte gemeldet werden.
Im Klartext besteht die einzige Lösung darin, ein benanntes Rohr zu verwenden.
set -e
mkfifo p
command1 >p & pid1=$!
command2 <p
wait $pid1
In ksh, bash und zsh können Sie die Shell anweisen, einen Pipeline-Exit mit einem Status ungleich Null durchzuführen, wenn eine Komponente der Pipeline mit einem Status ungleich Null beendet wird. Sie müssen die pipefail
Option einstellen :
- ksh:
set -o pipefail
- Bash:
shopt -s pipefail
- zsh:
setopt pipefail
(oder setopt pipe_fail
)
In mksh, bash und zsh können Sie den Status jeder Komponente der Pipeline mithilfe der Variablen PIPESTATUS
(bash, mksh) oder pipestatus
(zsh) abrufen. Hierbei handelt es sich um ein Array, das den Status aller Befehle in der letzten Pipeline enthält (eine Verallgemeinerung von $?
).
which lss | echo $?
derecho
gestartet wird vor demwhich
Verlassen der ; Die Shell, für die die Befehlszeile generiertecho
wird, kann nicht wissen, wie der Exit-Statuswhich
später aussehen wird.