В каких случаях SIGHUP не отправляется на работу при выходе из системы?

10

Я прочитал ответ от пользователя, который утверждал, что работает

foo 2>&1 >& output.log &

приведет к fooпродолжению работы, даже когда они выходят из системы. По словам этого пользователя, это даже работало через соединения SSH.

Я действительно не верил в это, поскольку у меня сложилось впечатление, что в случае отключения от SSH или завершения TTY оболочка и, следовательно, ее процессы получат SIGHUP, что приведет к их завершению. Это, по моему предположению, было единственной причиной для использования nohupв таких случаях, или tmux, screenи др.

Затем я посмотрел в руководство glibc :

Этот сигнал также используется, чтобы сообщить о завершении процесса управления на терминале заданиям, связанным с этим сеансом; это завершение эффективно отключает все процессы в сеансе от управляющего терминала.

Кажется, это подтверждает мои мысли. Но, глядя дальше, он говорит :

Если процесс является лидером сеанса, у которого есть управляющий терминал, то сигнал SIGHUP отправляется каждому процессу в задании переднего плана, и управляющий терминал отсоединяется от этого сеанса.

Таким образом, это означает, что задания, помещенные в фоновом режиме, не получат SIGHUP?

К моему дальнейшему замешательству, я запустил интерактивный сеанс Zsh, запустил yes >& /dev/null &и набрал exitтекст, когда Zsh предупредил меня о том, что у меня выполняются задания, и после exitповторного набора текста сказал, что он SIGHUPed одно задание. То же самое в Bash оставляет работу запущенной ...

slhck
источник
В прошлом у меня были проблемы с сервером, который внезапно отключался через ssh, и мой процесс просто продолжал работать, но без привязки к tty, поэтому мне пришлось снова войти в систему и отправить SIGHUP / TERM / KILL, чтобы завершить их. Итак, следуя той же логике, я только что проверил, набрал logoutи yesвсе еще работает.
Брайам
В дополнение к тому, отправляется ли сигнал SIGHUP, определен ли процесс обработчиком сигнала (и перехватывает SIGHUP) или маска сигнала являются дополнительными факторами того, завершается ли он при отправке этого сигнала. Так что то, что он продолжает работать после выхода из системы, не означает, что ему не был отправлен этот сигнал
Тим Б
Вы имеете в виду этот вопрос: serverfault.com/questions/115999/… ? Кажется, что ответ найден там - это RedHat, который не устанавливает shopt по умолчанию. Это особая особенность конфигурации RedHat.
Борис Бурков
@ Боб Нет, я не видел этого раньше, но это хороший ресурс. Спасибо!
Slhck
Рад, что это помогло. На самом деле Рафаэль имеет в виду и эту проблему.
Борис Бурков

Ответы:

18

Bash, кажется, отправляет SIGHUPтолько если он сам получил a SIGHUP, что, например, происходит, когда виртуальный терминал закрыт или когда соединение SSH прервано. Из документации :

По умолчанию оболочка завершается при получении SIGHUP. Перед выходом интерактивная оболочка отправляет SIGHUP всем работам, запущенным или остановленным. Остановленные задания отправляются SIGCONT, чтобы гарантировать получение SIGHUP. Чтобы предотвратить отправку оболочкой сигнала SIGHUP на конкретное задание, его следует удалить из таблицы заданий с помощью встроенной функции disown (см. Раздел «Встроенные элементы управления заданиями») или пометить, чтобы она не получала SIGHUP с помощью disown -h.

Поэтому, если вы напечатаете exitили нажмете Ctrl+, Dвсе фоновые процессы останутся, так как это не отправит сигнал зависания в Bash.

Вы можете заставить Bash предупредить вас о том, что все еще работают фоновые процессы с

shopt -s checkjobs

Существует возможность отправить при SIGHUPвыходе, если вы находитесь в интерактивной оболочке ( см. Здесь ). Но это не работает на моей машине с Bash 4.2.25. Может быть, это работает для вас

shopt -s huponexit
Рафаэль Аренс
источник
Итак, когда SSH-соединение прерывается, SIGHUPотправляется, иначе, с чистым выходом, задания продолжают выполняться? Это объясняет, что я видел.
Slhck
Да. Сигнал отбоя есть только для особого случая, когда соединение с пользователем прерывается.
Рафаэль Аренс
Давайте продолжим эту дискуссию в чате .
Мартин Кунев,
@npostavs спасибо за информацию, которую я добавил в ответ.
Рафаэль Аренс