2016-04-21 4 views
4

Dieses Shell-Skript verhält sich wie erwartet.Ist eine Pipeline garantiert in einer POSIX-Shell eine Subshell?

trap 'echo exit' EXIT 

foo() 
{ 
    exit 
} 

echo begin 
foo 
echo end 

Hier ist der Ausgang.

$ sh foo.sh 
begin 
exit 

Dies zeigt, dass das Skript während der Ausführung von foo beendet wird.

Jetzt sehen Sie das folgende Skript.

trap 'echo exit' EXIT 

foo() 
{ 
    exit 
} 

echo begin 
foo | cat 
echo end 

Der einzige Unterschied besteht darin, dass der Ausgang des foo in `cat geleitet wird. Jetzt sieht die Ausgabe wie folgt aus. Diese

begin 
end 
exit 

zeigt, dass das Skript nicht beendet, während foo Ausführung, weil end gedruckt wird.

Ich glaube, das passiert, weil in bash eine Pipeline verursacht eine Subshell geöffnet werden, so foo | cat entspricht (foo) | cat.

Ist dieses Verhalten in einer POSIX-Shell garantiert? Ich konnte im POSIX-Standard unter http://pubs.opengroup.org/onlinepubs/9699919799/ nichts finden, was bedeutet, dass eine Pipeline zu einer Subshell führen muss. Kann jemand bestätigen, ob dieses Verhalten zuverlässig ist?

Antwort

1

In 2.12 Shell Execution Environment Sie dieses Zitat finden:

A Subshell Umgebung wird als Duplikat der Shell-Umgebung geschaffen werden, mit der Ausnahme, dass Signal-Traps, die nicht ignoriert werden soll auf die Standardaktion eingestellt werden. Änderungen an der Subshell-Umgebung dürfen die Shell-Umgebung nicht beeinflussen. Befehlsersetzungen, Befehle, die in Klammern gruppiert sind, und asynchrone Listen müssen in einer Subshell-Umgebung ausgeführt werden. Darüber hinaus befindet sich jeder Befehl einer Pipeline mit mehreren Befehlen in einer Subshell-Umgebung. Als Erweiterung können jedoch einige oder alle Befehle in einer Pipeline in der aktuellen Umgebung ausgeführt werden. Alle anderen Befehle sollen in der aktuellen Shell-Umgebung ausgeführt werden.

Wo der Schlüsselsatz für diese Frage ist

Zusätzlich hat jeder Befehl einer Multi-Kommando-Pipeline ist in einer Subshell Umgebung; als Erweiterung können jedoch einige oder alle Befehle in einer Pipeline ohne die Erweiterung in der aktuellen Umgebung

So ausgeführt werden (die bash für Dinge verwendet wie lastpipe und, dachte ich, für das erste Element in einer Pipeline auch, aber scheinbar nicht oder zumindest nicht immer) es sieht so aus, als könnten Sie davon ausgehen, dass es für jeden Teil der Pipeline eine Subshell geben wird, aber die Ausnahme bedeutet, dass Sie sich nicht darauf verlassen können.

+0

Ist '(foo)' garantiert 'foo' in einer Subshell in einer POSIX-Shell auszuführen? –

+0

Das ist, was das Zitat oben und [Compound Commands] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04) auf mich zu deuten scheinen. Ich habe nirgends etwas von irgendwelchen Ausnahmen gesehen (und es wäre mir komisch, das zu berücksichtigen). –

Verwandte Themen