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

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

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

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

  • Есть ли способ использовать xargs через трубу?
  • Трубопроводы для выхода цикла предотвращают изменение локальной переменной
  • Bash - как сделать явный приоритет оператора без создания подоболочки
  • Разница между (x = 100) и {x = 100; }?
  • множество -е в подоболочке
  • Почему переменная видима в подоболочке?
  • Необычное поведение переменной в циклах while while
  • 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 
    Interesting Posts

    grub не будет устанавливать

    Как ограничить соединения с сервером OpenSSH с помощью секретных ключей обязательно с помощью фраз?

    Как я могу настроить /etc/kmscon/kmscon.conf для использования определенного шрифта a) и b) раскладки клавиатуры?

    Измените значок исполняемого файла из командной строки

    Пользовательская Launcher не появляется в Slingshot (eOS Freya)

    Как отправить вывод команды в буфер режима копирования экрана GNU

    Как разблокировать безопасно, не загрязняя текущий каталог в случае tarbomb?

    Не удается установить / удалить пакеты в Debian

    Как я могу изменить команду Linux на другую комбинацию клавиш?

    Jessie: невозможно загрузить ядро ​​3.16.0-4-amd64

    Статический ключ OpenVPN ip смысл / порядок?

    найти все слова, содержащие подстроку, и отобразить их в разных строках

    В чем разница между кэшированной памятью и используемой памятью?

    Что означают флаги в / proc / cpuinfo?

    Systemd продолжает пытаться установить не существующий fstab-определенный диск даже без automount

    Linux и Unix - лучшая ОС в мире.