Shell-Optionen festgelegt durchset
eingebautwerden in Unterschalen vererbt (zumindest in errexit
). Dies kann wie folgt bewiesen werden:
set -o errexit
function foo() {
echo "foo:$BASHPID"
false
echo 'after'
}
echo "main:$BASHPID"
( foo )
Allerdings scheinen die Optionen nicht übernommen zu sein inBefehlsersetzung, die laut Bash-Dokumentation ebenfalls Subshells sein sollten. Beweis:
set -o errexit
function foo() {
echo "foo:$BASHPID"
false
echo 'after'
}
echo "main:$BASHPID"
output=$(foo)
echo "output: $output"
Erwartete Ausgabe:
main:123
output: foo:124
Tatsächliche Ausgabe:
main:123
output: foo:124
after
Ist das zu erwarten oder ein Fehler?
Antwort1
sh
Ja, es wird erwartet, dass Bash außerhalb des POSIX-Modus (z. B. bei der Ausführung als ) errexit
standardmäßig innerhalb von Befehlsersetzungen zurückgesetzt wird.
Wenn Sie errexit
bei Befehlsersetzungen mit Bash 4.4 oder neuer beibehalten werden möchten, verwenden Sie:
inherit_errexit
Wenn gesetzt, übernimmt die Befehlsersetzung den Wert der
errexit
Option, anstatt ihn in der Subshell-Umgebung zu deaktivieren. Diese Option ist aktiviert, wenn der POSIX-Modus aktiviert ist.
(AusBash-Handbuch.)Ein weiterer Teil aus der Dokumentationhabe es deutlicher gemacht:
Das Aktivieren des POSIX-Modus hat zur Folge, dass die
inherit_errexit
Option festgelegt wird, sodass zum Ausführen von Befehlsersetzungen erstellte Subshells den Wert der-e
Option von der übergeordneten Shell erben.Wenn dieinherit_errexit
Option nicht aktiviert ist, löscht Bash die-e
Option in solchen Subshells.
Verifizieren:
$ bash -o errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:hashall:interactive-comments
$ bash -o errexit -O inherit_errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
In Bash 4.2 und älter errexit
wurde im ersteren angezeigt, aber immer noch effektiv deaktiviert:
$ bash-4.2 -o errexit c 'echo "$(false; echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
$ bash-4.2 -o posix -o errexit -c 'echo "<$(false; echo "$SHELLOPTS")> $?"'
<> 1