Warum führt das Beenden mit einem gespeicherten Rückkehrcode eines verschachtelten Befehls zu unterschiedlichen Rückkehrcodes in Dash und Bash?

8

Laufen

bash -c 'bash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'

führt dazu, test1dass auf der Konsole gedruckt wird und echo $?gedruckt wird, 1was meines Erachtens korrekt ist, da der Befehl mit dem [b/d]ash -czurückkehren sollte, was das Innere zurückgegeben hat, während

dash -c 'dash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'

führt zur gleichen Ausgabe, kehrt aber mit 0entsprechend zurück echo $?.

Ich möchte diesen Unterschied verstehen, um mein Verständnis von Shells und tragbarer Shell-Programmierung zu erweitern.

Ich verwende bash4.4.12 und dash0.5.8-2.3ubuntu1 unter Ubuntu 17.10 (Artful Aardvark).

Karl Richter
quelle

Antworten:

20

&>ist nicht in POSIX und wird von nicht unterstützt dash. Es wird als analysiert & >, daher wird der Befehl stattdessen im Hintergrund ausgeführt. Hintergrundbefehle erhalten aus Sicht des übergeordneten Elements den Beendigungsstatus Null , da sie zum Zeitpunkt des Lesens von $? Nicht beendet wurden.

Das ist auch der Grund, warum (zumindest für mich) die test1Ausgabe " " in meiner Eingabeaufforderung angezeigt wird, nachdem der Befehl beendet wurde.

Bash's &> fooentspricht> foo 2>&1 , und ein tragbares Skript sollte letzteres verwenden.

Michael Homer
quelle
5
&>ist in POSIX. Darauf &folgt >. In foo &> bar, foo &um fooim Hintergrund zu beginnen und > bareine Umleitung ohne Befehl durchzuführen. bashist nicht POSIX-kompatibel, wenn es anders interpretiert wird.
Stéphane Chazelas
4
Interessant genug ist, dass dies nicht in wiki.ubuntu.com/DashAsBinSh erwähnt wurde. Ich habe mir erlaubt , die Seite zu bearbeiten und aufzunehmen
Sergiy Kolodyazhnyy