Завершение родительского процесса также действительно завершает дочерние процессы, но не в интерактивной оболочке, почему? - PullRequest
0 голосов
/ 13 апреля 2020

Я только что столкнулся с удивительным поведением, которого никогда не видел прежде. Создайте сценарий оболочки 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 управлении заданиями Хотя я считаю, что это другая концепция, и она должна быть ортогональна текущему сценарию. Чего мне не хватает?

ПРИМЕЧАНИЕ: Ссылки на соответствующие примечания в любой документации, подтверждающие вашу точку зрения, очень приветствуются.

...