Я только что столкнулся с удивительным поведением, которого никогда не видел прежде. Создайте сценарий оболочки xxx
Bash:
#!/bin/bash
set -e
sleep 10
Запустите интерактивную оболочку Bash и запустите:
$ chmod +x xxx
$ ./xxx
Из другой оболочки запустите:
$ ps -fe | grep "xxx\|sleep" | grep -v grep; echo '----'; killall xxx; sleep 1; ps -fe | grep "xxx\|sleep" | grep -v grep
Вывод будет:
user 13526 1106 0 20:31 ? 00:00:00 /bin/bash /tmp/xxx
user 13528 13526 0 20:31 ? 00:00:00 sleep 10
----
user 13528 1106 0 20:31 ? 00:00:00 sleep 10
То есть дочерний процесс sleep
все еще висит, хотя xxx
уже завершен. Что?
ПРИМЕЧАНИЕ: Неудивительно, что setsid ./xxx
выявляет ту же проблему.
Наоборот, если вы запускаете xxx
через неинтерактивная оболочка, например, какая-то другая программа (для этого я использую функцию Emacs async-shell-command
, поскольку она будет внутренне выполнять fork
, setsid
и, наконец, execve
), тогда результат будет:
user 26184 30655 0 20:38 pts/8 00:00:00 /bin/bash /tmp/xxx
user 26185 26184 0 20:38 pts/8 00:00:00 sleep 10
----
То есть дочерний процесс sleep
завершен, поскольку родительский процесс завершился (вся группа управления процессом получила сигнал TERM
), как и ожидалось.
Мне известно о Bash управлении заданиями Хотя я считаю, что это другая концепция, и она должна быть ортогональна текущему сценарию. Чего мне не хватает?
ПРИМЕЧАНИЕ: Ссылки на соответствующие примечания в любой документации, подтверждающие вашу точку зрения, очень приветствуются.