
Есть два имени: аподоболочкаи аребенок-ракушка.
Да, дочерний процесс будет запущен любым из следующих способов:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Все ли они эквивалентны и имеют одно и то же имя? Все ли они имеют одни и те же свойства?
POSIXимеет это определение:
Среда выполнения оболочки состоит из ....
Но в последнем абзаце приведенной выше ссылки есть следующее:
Среда подоболочки должна быть создана как дубликат среды оболочки, за исключением того, что ловушки сигналов, которые не игнорируются, должны быть установлены на действие по умолчанию.
И особенно:
Подстановка команд, команды, сгруппированные с помощью скобок, и асинхронные списки должны выполняться в среде подоболочки. Кроме того, каждая команда многокомандного конвейера находится в среде подоболочки; ....
Там sh -c 'echo "Hello"'
не включено, следует ли его также называть подоболочкой?
решение1
Подоболочкадубликатысуществующая оболочка. Она имеет те же переменные¹, те же функции, те же опции и т. д. Под капотом создается подоболочка сfork
системный вызов²; дочерний процесс продолжает выполнять то, что от него ожидается, пока родительский процесс ждет (например, $(…)
) или продолжает свою работу (например, … &
) или иным образом выполняет то, что от него ожидается (например, … | …
).
sh -c …
не создает подоболочку. Она запускает другую программу. Эта программа оказывается оболочкой, но это просто совпадение. Программа может быть даже другой оболочкой (например, если вы запускаете ее sh -c …
из bash, а sh
это dash), т. е. совершенно другой программой, которая просто имеет значительное сходство в своем поведении. Под капотом запуск внешней команды ( sh
или любой другой) вызывает fork
системный вызов, а затемexecve
системный вызовзаменятьпрограмма оболочки в подпроцессе другой программы (здесь sh
).
¹ Включая $$
, но исключая некоторые переменные, специфичные для оболочки, такие как bash и mksh BASHPID
.
² По крайней мере, это традиционная и обычная реализация. Оболочки могут оптимизировать fork, если они могут имитировать поведение в противном случае. СмотритеВ чем именно разница между «подоболочкой» и «дочерним процессом»?
решение2
Среда подоболочки не должна существовать в отдельном процессе, ей просто нужно дублировать текущую среду выполнения. В ksh93
этом случае это делается механизмом virtual sub-shell
, который не вызывает fork()
. Это делает ksh93 очень быстрым на архаичных платформах, таких как Win-DOS
, поскольку Win-DOS
он чрезвычайно медленный с форком.
sh -c cmd
с другой стороны, создает новый процесс с оболочкой по умолчанию, которая не обязательно должна совпадать с вашей текущей интерактивной оболочкой.
Даже если sh
и ваша текущая оболочка идентичны, это не дублирует среду выполнения и, следовательно, не создает sub-shell
.