Подоболочка дублирует существующий снаряд. Он имеет те же переменные¹, те же функции, те же параметры и т. Д. Под капотом создается подоболочка с системным вызовом fork
²; дочерний процесс продолжает делать то, что от него ожидается, пока родитель ожидает (например, $ (…)
) или продолжает свою жизнь (например, … &
) или иначе делает то, что от него ожидается (например, … |…
).
sh -c…
не создает подоболочку. Запускает другую программу. Эта программа оказывается оболочкой, но это просто совпадение. Программа может даже быть другой оболочкой (например, если вы запускаете sh -c…
из bash, а sh
- это тире), то есть совершенно другой программой, которая просто случайно имеет значительное сходство в его поведении. Под капотом запуск внешней команды ( sh
или любой другой) вызывает системный вызов fork
, а затем системный вызов execve
для replace ] программа оболочки в подпроцессе другой программой (здесь sh
).
¹ Включая $$
, но исключая некоторые специфичные для оболочки переменные, такие как bash и mksh BASHPID
.
² По крайней мере, это традиционная и обычная реализация. Оболочки могут оптимизировать вилку, если в противном случае они могут имитировать поведение.
Соответствующие страницы руководства: fork (2) , execve (2) .