Existují tato dvě jména:subshell a skořápka pro děti .
Ano, podřízený proces bude spuštěn některým z těchto:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Jsou všechny rovnocenné a mají stejné jméno? Sdílejí všichni stejné vlastnosti?
POSIX má tuto definici:
Prostředí spouštění shellu se skládá z ….
Ale poslední odstavec výše uvedeného odkazu má toto:
Prostředí subshell by mělo být vytvořeno jako duplikát prostředí shellu, kromě toho, že depeše signálu, které nejsou ignorovány, musí být nastaveny na výchozí akci.
A speciálně:
Náhrada příkazů, příkazy, které jsou seskupeny se závorkami, a asynchronní seznamy se musí provádět v prostředí subshell. Kromě toho je každý příkaz z kanálu s více příkazy v prostředí subshell; ….
sh -c 'echo "Hello"'
není tam zahrnuto, mělo by se to také nazývat subshell?
Přijatá odpověď:
Subshell duplikuje stávající skořápka. Má stejné proměnné¹, stejné funkce, stejné možnosti atd. Pod kapotou se pomocí fork
vytvoří subshell systémové volání²; podřízený proces pokračuje dělat to, co se od něj očekává, zatímco rodič čeká (např. $(…)
) nebo pokračuje ve své životnosti (např. … &
) nebo jinak dělá to, co se od něj očekává (např. … | …
).
sh -c …
nevytváří subshell. Spustí další program. Ten program je náhodou shell, ale to je jen náhoda. Program může být dokonce jiný shell (např. když spustíte sh -c …
z bash a sh
je pomlčka), tj. zcela odlišný program, který má náhodou významné podobnosti ve svém chování. Pod kapotou se spustí externí příkaz (sh
nebo jakýkoli jiný) volá fork
systémové volání a poté execve
systémové volání nahradit shell program v podprocesu jiným programem (zde sh
).
¹ Včetně $$
, ale s výjimkou některých proměnných specifických pro shell, jako je bash a BASHPID
mksh .
² Alespoň taková je tradiční a obvyklá implementace. Shelly mohou optimalizovat vidlici, pokud mohou napodobit chování jinak.
Příslušné manuálové stránky:fork(2), execve(2).