Почему мой процесс все еще бежит, я выхожу из системы?

После входа в систему через ssh, Я ввожу эту команду bash:

sleep 50000000000000 &

Затем я kill -9 sleep родительский процесс процесса (т.е. bash). Затем окно терминала разъединяется одновременно.

Когда я вхожу в систему снова, я нахожу что sleep процесс все еще жив.

Вопрос: Почему может sleep процесс выживает, когда я выхожу из системы, и терминал закрывается? В моем уме, всем кроме демонов и nohup программы будут закрыты во время выхода из системы. Если sleep может выжить таким образом, делает это означает, что я могу использовать этот метод вместо nohup команда?

10
задан 14 October 2015 в 06:33

6 ответов

Tl; доктор:

Почему может sleep процесс выживает, когда я выхожу из системы, и терминал закрывается? В моем уме, всем кроме демонов и nohup программы будут закрыты во время выхода из системы. Если sleep может выжить таким образом, делает это означает, что я могу использовать этот метод вместо nohup команда?

Если bash экземпляр, порожденный ssh имеет huponexit набор опции, никакой процесс не будет завершен никем, означают на выход / выходят из системы, и когда huponexit опция установлена, с помощью kill -9 на оболочке не хорошая альтернатива использованию nohup на дочерних процессах оболочки; nohup на дочерних процессах оболочки все еще защитит их от SIGHUPs, не прибывающего из оболочки, и даже когда это не важно nohup должен все еще быть предпочтен, потому что это позволяет оболочке быть завершенной корректно.


В bash существует названная опция huponexit, который, если установленный сделает bash SIGHUP его дети на выход / выход из системы;

В интерактивном невходе в систему bash экземпляры, такой как в a bash экземпляр, порожденный gnome-terminal, эта опция проигнорирована; ли huponexit установлен или сброшен, bashдети никогда не будут SIGHUPped bash на выход;

В интерактивном входе в систему bash экземпляры, такой как в a bash экземпляр, порожденный ssh, эта опция не проигнорирована (однако, она сброшена по умолчанию); если huponexit установлен, bashдети будут SIGHUPped bash на выход / выход из системы; если huponexit сброшен, bashдети не будут SIGHUPped bash на выход / выход из системы;

Таким образом в общем выходе / регистрирующийся из интерактивного входа в систему bash экземпляр, если huponexit опция установлена, не сделает оболочку SIGHUP ее дети, и выходящий / регистрирующийся из интерактивного невхода в систему bash экземпляр не сделает оболочку SIGHUP ее дети независимо;

Это, однако, не важно в этом случае: использование kill -9 sleep выживет независимо, потому что, уничтожая его родительский процесс (bash) не оставит шанс для последнего сделать что-либо первому (т.е. например, если ток bash экземпляр был входом в систему bash экземпляр и huponexit опция была установлена к SIGHUP это).

Добавление к этому, в отличие от других сигналов (как сигнал SIGHUP, отправленный в bash), сигнал SIGKILL никогда не распространяется к дочерним процессам процесса, следовательно sleep даже не уничтожается;

nohup запускает процесс, неуязвимый для сигналов SIGHUP, который является чем-то другим; это предотвратит процесс, зависающий на прием сигнала SIGHUP, который в этом случае мог быть получен интерактивным входом в систему bash экземпляр в случае, если huponexit опция была установлена и оболочка, из которой выходят; так технически использование nohup запустить процесс в интерактивном входе в систему bash экземпляр с huponexit сброс опции будет препятствовать тому, чтобы процесс завис на прием сигнала SIGHUP, но выйти / выходить из оболочки не будет SIGHUP он независимо;

В целом, однако, когда nohup необходим для предотвращения сигналов SIGHUP, прибывающих из родительской оболочки, нет никакой причины предпочесть kill -9 на родительском методе к nohup на дочернем методе; вместо этого, это должно быть противоположное.

Уничтожение родителя с помощью kill -9 метод не оставляет шанс для родителя для выхода корректно при запуске дочернего элемента, использующего nohup метод позволяет родителю быть завершенным другими сигналами, такими как SIGHUP (для создания примера, который имеет смысл в контексте дочернего элемента, запущенного использовать nohup), которые позволяют этому выходить корректно.

6
ответ дан 23 November 2019 в 04:30

bash по умолчанию не отправляет вниз Сигнал HUP в дочерние процессы при выходе. Больше подробно (благодарит @kos), он никогда не делает это для оболочек невхода в систему.

Можно настроить удар, чтобы сделать это для оболочек входа в систему, если установлено опция huponexit. В терминале сделайте:

[romano:~] % bash -l

(этот запуск новая оболочка "входа в систему")

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

Теперь проверьте на sleep процесс:

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

... не выполнение: это получило Сигнал HUP и вышло согласно просьбе.

3
ответ дан 23 November 2019 в 04:30

Если sleep может выжить таким образом, если это означает, что я могу использовать этот метод вместо nohup команда?

kill -9 действительно не путь, которым нужно пойти. Это похоже на стрельбу с оружием на телевидении для выключения его. Помимо комичного компонента нет никакого преимущества. Процессы не могут поймать или проигнорировать SIGKILL. Если Вы не даете процессу шанс закончить то, что он делает, и вымойтесь, он может оставить поврежденные файлы (или другое состояние) вокруг и не сможет запуститься снова. kill -9 последняя надежда, когда ничто иное не работает.


Почему спящий процесс может выжить, когда я выхожу из системы, и терминал закрывается. В моем уме все кроме демона и nohup программы будет уничтожено когда выход из системы.

Что в Вашем случае происходит:

Родительский процесс sleep в настоящее время рабочий bash оболочка. Когда Вы kill -9 тот удар, процесс удара не имеет шанса отправить a SIGHUP к любому из его дочерних процессов, потому что SIGKILL (который отправляется kill -9) не catchable процессом. Спящий процесс продолжает работать. сон теперь стал процессом висячей строки.

init (PID 1), процесс делает механизм, назвал перепорождение. Это означает, что процесс init теперь становится родителем того осиротевшего процесса. init является исключением, процессы могут стать, это - ребенок, поскольку это собирает процессы, которые потеряли их исходный родительский процесс. Btw: демон (как sshd) делает это, "идя в фоновом режиме".

Если бы этого не произошло бы, осиротевший процесс позже (по окончании) стал бы процессом-зомби. Это - то, что происходит когда waitpid() не назван (ответственность родительского процесса, который не может быть выполнен когда, когда тот процесс был уничтожен). вызовы init waitpid() в определенном интервале для ухода от зомби childs.

2
ответ дан 23 November 2019 в 04:30

& запуски процесс в фоне. Если Вы тип ps -ef, Вы будете видеть, что родительский ID процесса (PPID) Вашего сна является Вашим ударом. Тогда выход из системы и логин снова. Процесс останется бежать за Вами выход из системы. После того, как Вы войдете в систему во второй раз, когда Вы бежите ps -ef снова. Вы будете видеть, что теперь родитель Вашего процесса сна будет процессом с id «1». Это - init, родитель всех процессов.

1
ответ дан 23 November 2019 в 04:30

Используя & заставит программу бежать как фон. Видеть, что программа на заднем плане использует bg команда и делает его бегущий как передний план снова, пробег fg.

Да, есть много способов поддерживать программу в рабочем состоянии даже главный терминал, из которого выходят.

0
ответ дан 23 November 2019 в 04:30

Здесь могут быть задействованы два вида SIGHUP.

Во-первых, потому что в такой ситуации оболочка будет так называемым контролирующим процессом (оболочка лидера сеанса, владеющая управляющим терминалом — псевдотерминалом, созданным при входе в систему ssh), драйвер терминала будет обязан отправить SIGHUP всем членам группы процессов переднего плана терминала, когда терминал отключен.

(Он также будет отправлять SIGHUP+SIGCONT остановленным фоновым процессам (группам потерянных процессов)).

Вы исключили такую ​​системную отправку SIGHUP путем фонового процесса, находясь в интерактивной оболочке. Такая фоновая обработка поместит процесс(ы) в отдельную группу процессов, которая не будет группой процессов переднего плана терминала, и поэтому драйвер не будет отправлять SIGHUP таким процессам.

Фоновый фон сам по себе не проблема, но вам нужно запустить фон из неинтерактивной оболочки (интерактивные оболочки помещают фоновые процессы в отдельные группы процессов) и часть группы процессов переднего плана:

#from a ssh login shell
bash -c 'echo $$; sleep 1000 & sleep 1000 && wait' 
#a backgrounded and a nonbackgrounded sleep, both in the foreground process group

Теперь, если бы вы kill -9 эхо-сообщение pid оболочки с другого терминала, оба спящих процесса получат SIGHUP от драйвера терминала (обработчик сигнала, зарегистрированный в sigaction, будет считывать pid как si_pid==0).

Во-вторых, это SIGHUP, отправляемые оболочкой в ​​зависимости от ее настроек (si_pid!=0). Интерактивный bash повторно отправляет полученные SIGHUP всем своим заданиям переднего плана. Такое поведение позволяет вам иметь несколько интерактивных bash друг над другом (например, если вы запускаете bash из bash для входа и, возможно, из некоторых экземпляров bash (без & в конце) от него) и будьте уверены, что SIGHUP из первого (управляющего) bash будет отправлен, даже если каждый управляющий bash создаст свою собственную группу процессов, и поэтому SIGHUP, отправленный драйвером терминала, не будет быть в состоянии добраться до потомков. (Это есть не во всех оболочках. Например, в Dash нет.) Bash также повторно отправляет SIGHUP своим фоновым процессам, но только если параметр huponexit включен, а задание не т отрекся изд. Ни одна из этих повторных отправок не может применяться, если оболочка была принудительно уничтожена с помощью SIGKILL (kill -9).

Редактировать:

Только что нашел очень актуальный ответ https://stackoverflow.com/a/32786211/1084774 от gavv, в котором есть еще пара деталей.

0
ответ дан 17 September 2020 в 15:54

Другие вопросы по тегам:

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