Баш и подоболочки

Из того, что я собираю из интерактивных документов, следующее должно порождать подоболочку для части команды, встроенной в {} :

 $ bash -c '{ sleep 10; echo "Sleeping process", $$; } & echo $$; ' 11237 Sleeping process, 11237 

Однако, как вы можете видеть, в обоих случаях идентификатор процесса одинаков. Что мне не хватает? Спасибо за любые указатели.

2 Solutions collect form web for “Баш и подоболочки”

{} Просто группирует команды вместе в текущей оболочке, а () запускает новую подоболочку. Однако то, что вы делаете, заключается в том, чтобы сгруппировать команды в фоновом режиме, что действительно является новым процессом; если бы это было в текущем процессе, это не могло быть основано. Легче, ИМХО, видеть такую ​​вещь с strace:

 sauer@humpy:~$ strace -f -etrace=process bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL; } & echo $BASHPID;' > /tmp/file execve("/bin/bash", ["bash", "-c", "{ sleep 10; echo \"Sleeping proce"...], [/* 20 vars */]) = 0 arch_prctl(ARCH_SET_FS, 0x7f15a90da700) = 0 clone(Process 25347 attached child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f15a90da9d0) = 25347 [pid 25346] exit_group(0) = ? clone(Process 25348 attached (waiting for parent) Process 25348 resumed (parent 25347 ready) child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f15a90da9d0) = 25348 [pid 25348] execve("/bin/sleep", ["sleep", "10"], [/* 20 vars */] <unfinished ...> [pid 25347] wait4(-1, Process 25347 suspended <unfinished ...> [pid 25348] <... execve resumed> ) = 0 [pid 25348] arch_prctl(ARCH_SET_FS, 0x7f922ad16700) = 0 [pid 25348] exit_group(0) = ? Process 25347 resumed Process 25348 detached <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 25348 --- SIGCHLD (Child exited) @ 0 (0) --- wait4(-1, 0x7fffaa432ad8, WNOHANG, NULL) = -1 ECHILD (No child processes) exit_group(0) = ? Process 25347 detached sauer@humpy:~$ cat /tmp/file 25346 Sleeping process, 25347, 1 

Обратите внимание, что команда bash запускается, а затем создает новый дочерний элемент с clone() . Использование опции -f для strace означает, что она также следует за дочерними процессами, показывая еще одну вилку (ну, «клон»), когда она запускает сон. Если вы выйдете из -f, вы увидите только один клон-вызов, когда он создает фоновый процесс:

 sauer@humpy:~$ strace -etrace=clone bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL; } & echo $BASHPID;' > /tmp/file clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f2bdd5399d0) = 26394 sauer@humpy:~$ strace -etrace=process bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL; } & echo $BASHPID;' > /dev/null execve("/bin/bash", ["bash", "-c", "{ sleep 10; echo \"Sleeping proce"...], [/* 20 vars */]) = 0 arch_prctl(ARCH_SET_FS, 0x7fd01ae86700) = 0 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd01ae869d0) = 26706 exit_group(0) = ? 

Если вы действительно хотите узнать, как часто вы создаете новые процессы, вы можете упростить это, даже если смотреть только на fork и clone calls:

 sauer@humpy:~$ strace -etrace=fork,clone bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL; } & echo $BASHPID;' > /dev/null clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f467fa769d0) = 27025 

Обновить:

См. Ответ выше. С {} я не создаю подоболочку. Вместо этого заднее заземление дает мне ответ, который я искал.

Хорошо, так что в основном я использовал неправильный «индикатор» создаваемых подоболочек. Я узнал о BASHPID отсюда и использовал это в дополнение к BASH_SUBSHELL , я вижу, что подоболочка действительно создается.

Команда тестирования:

 $ bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL; } & echo $BASHPID; ' 12074 Sleeping process, 12075, 1 

Еще одна тестовая команда также показывает идентификатор родительского процесса для оболочки и подоболочки:

 $ bash -c '{ sleep 10; echo "Sleeping process", $BASHPID, $BASH_SUBSHELL, $PPID; } & echo $BASHPID, $PPID; ' 12411, 9128 $ Sleeping process, 12412, 1, 9128 
Linux и Unix - лучшая ОС в мире.