Почему мой процесс все еще работает после выхода из системы?

После входа через ssh я набираю эту команду в bash :

спать 50000000000000 & 

Затем я убиваю -9 родительский процесс (сна т. е. bash ). Затем окно терминала отключается одновременно.

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

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

10
10.14.2015, 06:33
6 ответов

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

1
11.23.2019, 03:30

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

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

0
11.23.2019, 03:30
  • 1
    Спасибо. справочная страница bash немного сбивает с толку. В нем говорилось, что :«Перед выходом интерактивная оболочка повторно отправляет SIGHUP всем заданиям, запущенным или остановленным». НО на самом деле оболочка отправляет SIGHUP только заданиям **forground **. фоновые процессы не имеют возможности получить сигнал SIGHUP (, если не изменить параметры оболочки 'huponexit' ) –  tom_cat 10.14.2015, 07:08
  • 2
    @kos, возможно, ты прав. Я делаю вышеуказанный вывод из этого поста :http://stackoverflow.com/questions/4298741/how-bash-handles-the-jobs-when-logoutтеперь я еще больше запутался. –  tom_cat 10.14.2015, 07:55
  • 3
    Лучшее, что я могу придумать, это http://www.sqlines.com/sql-server-to-mysqlПлатное программное обеспечение, но у них есть пробная версия :http://www.sqlines.com/download -. 121 ---2395777 -@tom _cat Вернемся к этому снова, дважды подумав об этом :просто нет случая, когда оболочка может *выйти *с запущенным процессом переднего плана, это может быть SIGHUPped или что-то в этом роде, но это не так. *выход *. Так что правильно, это относится только к фоновым процессам, потому что обратное не имеет смысла. Однако из дальнейших исследований следует также отметить, что `huponexit `работает только в оболочках входа в систему, таких как оболочка, полученная через `ssh `(. а не, скажем, в оболочке, полученной через `gnome -терминал `) –  Community 10.14.2015, 10:42

Тл; др :

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

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


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

В интерактивном не -логин экземпляры bash , такие как экземпляр bash , порожденный терминалом gnome -, этот параметр игнорируется; установлен ли huponexit или нет, bash дочерние элементы никогда не будут получать SIGHUP от bash при выходе;

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

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

Это, однако, в данном случае не имеет значения :использование kill -9 sleep выживет в любом случае, потому что его родительский процесс будет уничтожен (баш )не оставит шанса последнему сделать что-либо первому (т. е., например, если текущий экземпляр 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
11.23.2019, 03:30
  • 1
    Другими словами, если у меня есть скрипт, который был помещен в фоновый режим, он все равно будет работать, даже если я уничтожу родительский процесс, например. моя оболочка не так ли? как можно убить этот скрипт? –  Sergiy Kolodyazhnyy 10.14.2015, 07:22
  • 2
    @Serg Если у вас есть PID, просто убейте PID; если вы не сохранили PID, но можете идентифицировать процесс по его имени, `ps -e | процесс grep `должен перечислять процессы вместе с PID (или лучше просто `pgrep -x процесс `, если вы уверены, что соответствуете этому единственному процессу, а не ненужным вещам ); проблема в том, что когда вы завершаете процесс командой `kill -9 `, его дочерние элементы становятся собственностью `выскочки `, поэтому их первоначальный PPID теряется, а их PPID меняется на PID выскочки, что делает их до неузнаваемости (AFAIK ), но по их имени или PID –  Community 10.14.2015, 07:37
  • 3
    @kos При каком условии `nohup `не сможет предотвратить зависание процесса при получении сигнала SIGHUP от родительского процесса? Я пытаюсь запустить процесс в фоновом режиме (в терминале оболочки PuTTY SSH )с помощью `nohup & `. Когда я выхожу из системы, нажимая кнопку PuTTY `X `, фоновый процесс немедленно завершается. Когда я выхожу из системы, набрав `exit `в терминале оболочки PuTTY SSH, процесс продолжит работать в фоновом режиме. –  userpal 04.23.2016, 05:25

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

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


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

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

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

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

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

2
11.23.2019, 03:30
  • 1
    Процесс выживает даже при вежливых сигналах типа `TERM `или `HUP ` –  heemayl 10.14.2015, 08:06
  • 2
    @heemayl HUP зависит от конфигурации оболочки :`гупонекст `. И TERM будет ждать, пока сон не закончится. В случае команды OPs sleep это будут тысячи лет = ) –  Community 10.14.2015, 08:29

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

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

[romano:~] % bash -l 

(это запустит новую оболочку «login» )

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
11.23.2019, 03:30
  • 1
    @kos ---да, ты прав, но... так почему, если я `сплю 1000 & ; выход ``сон `выживает? Обратите внимание, что если я `уничтожу -HUP `, процесс `сна `его *завершит *. И даже если `гупонэкзит `установлен, `сон `сохраняется. Запутался... (Я постараюсь лучше понять и изменить ответ, иначе я его удалю ). –  Rmano 10.14.2015, 11:03

Здесь могут быть задействованы два вида 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от драйвера терминала (a sigaction-зарегистрированный обработчик сигнала будет читать pid отправителя как si_pid==0).

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

Изменить :

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

0
09.17.2020, 15:54

Теги

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