Ich muss eine Reihe von Pipe-Shell-Befehlen von einem Nicht-BASH-Skript (nämlich PHP-Skript) wie folgt ausführen:
command1 | command2 | command3
Wenn also ein command1
Fehler mit einem Exit-Code ungleich Null auftritt, schlägt auch jeder andere Befehl fehl. Bisher habe ich mir Folgendes ausgedacht:
set -o pipefail && command1 | command2 | command3
Aber obwohl es vom Terminal aus gut läuft, erzeugt es dies, wenn es vom Skript ausgeführt wird:
sh: 1: set: Unzulässige Option -o pipefail
linux
command-line
shell
pipe
Desmond Hume
quelle
quelle
/bin/sh
nicht gefälltset -o pipefail
. Ist es tatsächlichbash
verschleiert oder ist es eine andere Hülle? Wannbash
wird ausgeführt als/bin/sh
, akzeptiert esset -o pipefail
?/bin/sh set -o pipefail
heißt es/bin/sh: 0: Can't open set
(dasselbe mitsudo
). Hoffe ich habe es richtig getestet. Das System ist Ubuntu 12./bin/sh -c "set -o pipefail"
; Die Shell hat versucht, ein Skript im aktuellen Verzeichnis auszuführen,set
und es wurde nicht gefunden./bin/sh -c "set -o pipefail"
funktioniert jedochbash -c "set -o pipefail"
nicht./bin/sh
dem es nicht erkannt wirdset -o pipefail
. Folglich müssen Sie sicherstellen, dass das Skript/bin/bash
von ausgeführt wird/bin/sh
. Oder, wenn Sie zuversichtlich sind, mutig - und wahrscheinlich tollkühn - ändern/bin/sh
, um eine Verknüpfung zu oder eine Kopie von zu sein,/bin/bash
anstatt der Shell, mit der sie derzeit verknüpft ist, oder einer Kopie von. Wenn Sie sicher sind, dass dies der Fall/bin/sh
istbash
, verwenden Sie ein Verhalten, dasbash
beim Ausführen als nicht verfügbar gemacht wird/bin/sh
. Verwenden Siebash
alsbash
.Antworten:
Über die Bash-Befehlszeile müssten Sie eine Subshell aufrufen, um zu vermeiden
pipefail
, dass sie später festgelegt wird:Dies würde den Effekt der
pipefail
Option auf die durch die Klammern erzeugte Unterschale begrenzen(...)
.Ein echtes Beispiel:
Wenn Sie einen expliziten Shell-Aufruf mit der
-c
Option verwenden, benötigen Sie keine Subshell, weder mitbash
noch mit einemsh
Alias fürbash
:Da Ihr
sh
diepipefail
Option nicht akzeptiert , müsste ich davon ausgehen, dass es sich entweder um eine ältere oder modifizierte Version handeltbash
- oder dass es sich tatsächlich um eine andere Shell handelt.quelle
$
im ersten Teil des Befehls nur eine Shell-Eingabeaufforderung enthalten? In beide Richtungen versucht, hat nicht wirklich funktioniert. Derbash -c
Weg funktioniert immer, aber nicht zu elegant.Ich bin mir nicht sicher, warum es oben nicht erwähnt wurde, aber es ist möglich, es explizit zu deaktivieren
pipefail
, indem ich benutzeset +o pipefail
.Wenn Sie ein Fragment ausführen und sich über die
pipefail
bereits festgelegte Menge nicht sicher sind , können Sie dies mit der Subshell wie oben vorgeschlagen verwenden:quelle
Sie können $ (command1) in Kombination mit $? :
Druckt "abc"
Druckt "".
"[$? -eq 0] &&" bedeutet, dass der folgende Befehl nur ausgeführt wird, wenn der vorherige erfolgreich war.
Das beantwortet Ihre Frage nicht, aber es ist eine Lösung für Ihr Problem.
quelle
command1 && command2 && command3