Исследование, вызванное тем, что задача все еще выполняется после выхода из оболочки Linux.

Linux Shell

При подключении к оболочке сервера по SSH сегодня был выполнен скрипт Python и переданCTRL+Zа такжеbgПоставьте его работать в фоновом режиме.

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

Поэтому я проверил соответствующую документацию, чтобы выяснить, почему.

Как правило

Когда мы входим в интерактивную оболочку, выполняемые команды обычно получаются из текущего процесса оболочки и запускаются как его дочерние процессы.

При выходе из оболочки все задачи (подпроцессы) получают сигнал SIGHUP, отправленный оболочкой, и завершаются.

Чтобы избежать завершения задачи при выходе из оболочки, обычно передайтеnohup,disown,setsidДождитесь выполнения команды.

Для конкретных методов, пожалуйста, обратитесь к этой статье:Советы по Linux: несколько способов обеспечить надежную работу процессов в фоновом режиме

проводить исследования

Чтобы найти причину, мы воспроизвели проблему.

Сначала войдите в удаленную оболочку и выполнитеsleep 3600 &команда, мы можем пройтиjobsПосмотрите, как команда работает в фоновом режиме.

root@VPS-WRAY:~# sleep 3600 &
[1] 23960
root@VPS-WRAY:~# jobs
[1]+  Running                 sleep 3600 &

использоватьpsКоманда для просмотра статуса процесса:

root@VPS-WRAY:~# ps -Hf
UID        PID  PPID  C STIME TTY          TIME CMD
root     23946 23944  0 16:13 pts/0    00:00:00 -bash
root     23960 23946  0 16:13 pts/0    00:00:00   sleep 3600
root     23961 23946  0 16:13 pts/0    00:00:00   ps -Hf

Вы можете видеть, что ppid спящего процесса — 23946, что означает, что его родительский процесс — bash.

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

После выхода из системы снова войдите в удаленную оболочку, чтобы просмотреть статус процесса:

root@VPS-WRAY:~# ps -ef | grep sleep
root     23960     1  0 16:13 ?        00:00:00 sleep 3600
root     24003 23993  0 16:27 pts/1    00:00:00 grep sleep

сон не закончился! И его родительский процесс становится процессом инициализации (ppid = 1).

Давайте посмотрим, может ли ручная отправка сигнала SIGHUP завершить процесс сна:

root@VPS-WRAY:~# kill -s SIGHUP 23960
root@VPS-WRAY:~# ps -ef | grep sleep
root     24077 23993  0 16:35 pts/1    00:00:00 grep sleep

Процесс сна был остановлен.

Это показывает, что проблема заключается в оболочке.Когда мы выходим из оболочки, процесс bash завершается, но он не отправляет сигнал SIGHUP дочернему процессу, спящему, поэтому спящий процесс становится осиротевшим процессом, а затем преуспевает в init, поэтому ppid становится For 1, продолжайте работать в системе.

Но разве оболочка не отправляет автоматически сигнал SIGHUB при выходе?

причина

Следующие абзацы взяты изBASH man page:

The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP. To prevent the shell from sending the signal to a particular job, it should be removed from the jobs table with the disown builtin (see SHELL BUILTIN COMMANDS below) or marked to not receive SIGHUP using disown -h.

If the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an interactive login shell exits.

То есть вhuponexitПри установленном параметре интерактивная оболочка отправляет сигнал SIGHUP всем задачам перед выходом. Однако этот параметр не установлен по умолчанию в bash, поэтому дочернему процессу не будет отправлен сигнал SIGHUP при выходе.

пройти черезshopt -pкоманда может перечислить параметры оболочки,-uзначит не установлено,-sУказывает, что он установлен:

root@VPS-WRAY:~# shopt -p | grep huponexit
shopt -u huponexit

Этот параметр не установлен, что объясняет, почему обычные фоновые задачи продолжают выполняться при выходе из оболочки.

мы можем пройтиshopt -s huponexitкоманда для установки этой опции, напишите ее в/etc/profileОн гарантирует завершение фоновой задачи, отправляя фоновой задаче сигнал SIGHUP каждый раз при выходе из оболочки.

Конечно, с другой точки зрения, это тоже способ добиться длительного выполнения задач в фоновом режиме, а наоборот, использовать с самого началаnohup,disownБыло бы более безопасно дождаться выполнения команды.

Статьи по Теме