В чем разница между выполнением в подоболочках и использованием команды & vs coproc?

Я недавно читал о подоболочках в linux. В качестве примера использовался sleep 10.

(sleep 10)  -  subshell
sleep 10&   - background process
coproc sleep 10  

Было написано, что первая команда выполняется в подоболочке. Второй — фоновый процесс без участия подоболочки. И третий был комбинацией обоих. Я тестировал с помощью ps -ef, и все эти команды показывают создание подоболочки. Есть ли разница между фоновым процессом, использующим & и и подоболочки? Также coproc, похоже, делает то же самое. Я совершенно сбит с толку. Любой свет по теме будет оценен.

1
30.06.2020, 08:37
1 ответ

В вашей оболочке 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; }
2
18.03.2021, 23:23

Теги

Похожие вопросы