Я недавно читал о подоболочках в linux. В качестве примера использовался sleep 10.
(sleep 10) - subshell
sleep 10& - background process
coproc sleep 10
Было написано, что первая команда выполняется в подоболочке. Второй — фоновый процесс без участия подоболочки. И третий был комбинацией обоих.
Я тестировал с помощью ps -ef
, и все эти команды показывают создание подоболочки. Есть ли разница между фоновым процессом, использующим & и и подоболочки? Также coproc, похоже, делает то же самое. Я совершенно сбит с толку. Любой свет по теме будет оценен.
В вашей оболочке sleep
не является встроенной командой оболочки, поэтому она должна выполняться в отдельном процессе в любом случае (, который будет отличаться от ksh93
или mksh
, где sleep
встроен в ).
(sleep 10)
реализует среду подоболочки . Идея состоит в том, что любые изменения в среде оболочки (псевдонимов, переменных, функций, umask, рабочего каталога, перенаправлений... ), сделанные внутри (...)
, влияют только на это и теряются при возврате (...)
.
В большинстве оболочек это реализуется путем разветвления дочернего процесса. Не все оболочки делают это таким образом. ksh93
вместо этого сохраняет предыдущие настройки среды в стеке и восстанавливает их при выходе и в этом случае не разветвляется.
Во многих оболочках в качестве оптимизации, если последняя команда в подоболочке является внешней командой (, например sleep
в вашем случае ), и trap
не установлено, оболочка не разветвляется. процесс для его запуска, но запускает его непосредственно в дочернем процессе, так как этот процесс в любом случае впоследствии не понадобится.
В случае оболочки bash
это происходит только в том случае, если команда является единственной командой в подоболочке (, что также имеет место здесь ).
sleep 10&
и coproc sleep 10
также запускают среду подоболочки, но в этих случаях они должны выполняться с использованием дочернего процесса, поскольку у вас есть два параллельных потока выполнения. Разница между ними заключается в том, что в случае coproc
подоболочка имеет свой стандартный ввод и стандартный вывод, подключенные к двум каналам для взаимодействия с родителем.
Как и в случае (...)
, если подоболочка состоит только из одной команды, эта команда выполняется непосредственно в процессе оболочки.
Чтобы лучше увидеть разницу,вы, вероятно, захотите запустить подоболочки, которые запускают более одной команды, например:
{ ps; echo done; } # no subshell
(ps; echo done)
{ ps; echo done; } &
coproc { ps; echo done; }