Es gibt diese zwei Namen:eine Subshell und eine Kind-Shell .
Ja, ein untergeordneter Prozess wird durch Folgendes gestartet:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Sind alle gleichwertig und haben denselben Namen? Haben alle die gleichen Eigenschaften?
POSIX hat diese Definition:
Eine Shell-Ausführungsumgebung besteht aus ….
Aber der letzte Absatz des obigen Links hat folgendes:
Eine Subshell-Umgebung soll als Duplikat der Shell-Umgebung erstellt werden, außer dass Signal-Traps, die nicht ignoriert werden, auf die Standardaktion gesetzt werden.
Und speziell:
Befehlssubstitution, mit Klammern gruppierte Befehle und asynchrone Listen sollen in einer Subshell-Umgebung ausgeführt werden. Außerdem befindet sich jeder Befehl einer Multi-Befehls-Pipeline in einer Subshell-Umgebung; ….
Der sh -c 'echo "Hello"'
ist dort nicht enthalten, sollte das auch Subshell genannt werden?
Akzeptierte Antwort:
Eine Subshell dupliziert die vorhandene Schale. Es hat die gleichen Variablen¹, die gleichen Funktionen, die gleichen Optionen usw. Unter der Haube wird mit dem fork
eine Subshell erstellt Systemaufruf²; der untergeordnete Prozess fährt fort, das zu tun, was von ihm erwartet wird, während der übergeordnete Prozess wartet (z. B. $(…)
) oder mit seinem Leben fortfährt (z. B. … &
) oder auf andere Weise das tut, was von ihm erwartet wird (z. B. … | …
).
sh -c …
erstellt keine Unterschale. Es startet ein anderes Programm. Dieses Programm ist zufällig eine Shell, aber das ist nur ein Zufall. Das Programm kann sogar eine andere Shell sein (z. B. wenn Sie sh -c …
ausführen von bash und sh
ist Bindestrich), d.h. ein völlig anderes Programm, das zufällig signifikante Ähnlichkeiten in seinem Verhalten aufweist. Unter der Haube führt das Starten eines externen Befehls (sh
oder irgendein anderer) ruft den fork
auf Systemaufruf und dann execve
Systemaufruf zum Ersetzen das Shell-Programm im Unterprozess durch ein anderes Programm (hier sh
).
¹ Einschließlich $$
, aber ohne einige Shell-spezifische Variablen wie bash und BASHPID
von mksh .
² Das ist zumindest die traditionelle und übliche Implementierung. Shells können den Fork wegoptimieren, wenn sie das Verhalten anderweitig nachahmen können.
Relevante Handbuchseiten:fork(2), execve(2).