
Es gibt diese zwei Namen:Unterschaleund einKinderschale.
Ja, durch Folgendes wird ein untergeordneter Prozess gestartet:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Sind alle gleichwertig und haben den gleichen Namen? Haben alle die gleichen Eigenschaften?
POSIXhat diese Definition:
Eine Shell-Ausführungsumgebung besteht aus …
Aber der letzte Absatz des obigen Links enthält Folgendes:
Es soll eine Subshell-Umgebung als Duplikat der Shell-Umgebung erstellt werden, mit der Ausnahme, dass Signal-Traps, die nicht ignoriert werden, auf die Standardaktion gesetzt werden sollen.
Und speziell:
Befehlsersetzungen, mit Klammern gruppierte Befehle und asynchrone Listen müssen in einer Subshell-Umgebung ausgeführt werden. Darüber hinaus befindet sich jeder Befehl einer Multi-Befehls-Pipeline in einer Subshell-Umgebung; ....
Das sh -c 'echo "Hello"'
ist dort nicht enthalten, sollte das auch als Unterschale bezeichnet werden?
Antwort1
Eine UnterschaleDuplikatedie vorhandene Shell. Sie hat die gleichen Variablen¹, die gleichen Funktionen, die gleichen Optionen usw. Unter der Haube wird eine Subshell mit demfork
Systemaufruf²; der untergeordnete Prozess führt das von ihm erwartete Verhalten aus, während der übergeordnete Prozess wartet (z. B. $(…)
), mit seinem Leben fortfährt (z. B. … &
) oder anderweitig das von ihm erwartete Verhalten ausführt (z. B. … | …
).
sh -c …
erstellt keine Subshell. 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 es sh -c …
von Bash ausführen und sh
es Dash ist), d. h. ein völlig anderes Programm, das zufällig erhebliche Ähnlichkeiten in seinem Verhalten aufweist. Unter der Haube ruft das Starten eines externen Befehls ( sh
oder eines anderen) den fork
Systemaufruf auf und dann denexecve
Systemaufruf anersetzendas Shell-Programm im Unterprozess durch ein anderes Programm (hier sh
).
¹ Einschließlich $$
, aber ohne einige Shell-spezifische Variablen wie die von bash und mksh BASHPID
.
² Zumindest ist das die traditionelle und übliche Implementierung. Shells können den Fork optimieren, wenn sie das Verhalten anderweitig nachahmen können. SieheWas ist der genaue Unterschied zwischen einer „Subshell“ und einem „Kindprozess“?
Antwort2
Eine Sub-Shell-Umgebung muss nicht in einem separaten Prozess existieren, sie muss nur die aktuelle Ausführungsumgebung duplizieren. In ksh93
wird dies durch einen Mechanismus erreicht virtual sub-shell
, der nicht aufruft fork()
. Dies macht ksh93 auf veralteten Plattformen wie sehr schnell Win-DOS
, da Win-DOS
es beim Forking extrem langsam ist.
sh -c cmd
Auf der anderen Seite wird ein neuer Prozess mit der Standard-Shell erstellt, die nicht mit Ihrer aktuellen interaktiven Shell identisch sein muss.
Auch wenn sh
und Ihre aktuelle Shell identisch sind, wird dadurch die Ausführungsumgebung nicht dupliziert und somit kein erstellt sub-shell
.