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