로그 아웃 한 후에도 프로세스가 계속 실행되는 이유는 무엇입니까?


10

를 통해 로그인 한 후 ssh다음 명령을 입력합니다 bash.

sleep 50000000000000 &

그럼 난 프로세스의 부모 프로세스 (예 ). 그런 다음 터미널 창이 동시에 연결 해제됩니다.kill -9sleepbash

다시 로그인해도 sleep프로세스가 여전히 활성 상태 임을 알 수 있습니다.

질문 : sleep로그 아웃하고 터미널을 닫을 때 프로세스가 지속되는 이유는 무엇 입니까? 내 생각에, 데몬과 nohup프로그램을 제외한 모든 것은 로그 아웃하는 동안 죽을 것이다. sleep이런 식으로 살아남을 수 있다면 nohup명령 대신이 방법을 사용할 수 있습니까?


3
&프로세스를 백그라운드 (데몬과 같은)로 분기하고 로그 아웃하더라도 계속 실행됩니다.
Aizuddin Zali

답변:


6

Tl; dr :

sleep로그 아웃하고 터미널을 닫을 때 프로세스가 지속되는 이유는 무엇 입니까? 내 생각에, 데몬과 nohup프로그램을 제외한 모든 것은 로그 아웃하는 동안 죽을 것이다. sleep이런 식으로 살아남을 수 있다면 nohup명령 대신이 방법을 사용할 수 있습니까?

bash의해 생성 된 인스턴스 sshhuponexit옵션이 설정되어 있지 않으면 종료 / 로그 아웃시 어떠한 방법으로도 프로세스가 종료되지 않으며 huponexit옵션이 설정된 kill -9경우 쉘에서 사용 nohup하는 것이 쉘의 자식 프로세스 에서 사용 하는 것의 좋은 대안이 아닙니다 . nohup쉘의 자식 프로세스는 여전히 쉘에서 나오지 않는 SIGHUP으로부터 프로세스를 보호하며, 중요하지 않은 경우에도 nohup쉘을 정상적으로 종료 할 수 있기 때문에 여전히 선호됩니다.


여기 bash에 옵션이 huponexit있는데, 설정하면 bash종료 / 로그 아웃시 SIGHUP을 자식으로 만듭니다 .

에 의해 생성 된 인스턴스 와 같은 대화 형 비 로그인 bash 인스턴스 에서는이 옵션이 무시됩니다. 설정 또는 설정 해제 여부에 관계없이 종료시 자녀는 절대 SIGHUP되지 않습니다 .bashgnome-terminalhuponexitbashbash

에 의해 생성 된 인스턴스 와 같은 대화식 로그인 bash 인스턴스 에서이 옵션은 무시되지 않습니다 (단, 기본적으로 설정되어 있지는 않습니다). 경우 설정, 의 아이들에 의해 SIGHUPped 될 것입니다 종료 / 로그 아웃시; 경우 설정 해제, 의 아이들에 의해 SIGHUPped되지 않습니다 종료 / 로그 아웃시;bashsshhuponexitbashbashhuponexitbashbash

따라서 일반적으로 대화식 로그인 bash인스턴스 에서 종료 / 로그 아웃하는 경우 ( huponexit옵션이 설정되지 않은 경우 쉘 SIGHUP을 자식으로 만들지 않으며 대화식 비 로그인 bash인스턴스 에서 종료 / 로그 아웃 하면 쉘 SIGHUP을 자식으로 만들지 않습니다. 상관없이;

그러나이 경우에는 무의미 kill -9 sleep합니다. 부모 프로세스를 bash종료하면 ( ) 후자가 전자에 대해 아무것도 할 가능성이 없기 때문에 (예 : 현재 bash인스턴스가 로그인 bash인스턴스 인 경우 ) 사용 여부에 관계없이 사용 합니다. 그리고 huponexit옵션)를 SIGHUP하기 위해 설정되었다.

여기에 SIGHUP 신호와 같은 다른 신호와 달리 bashSIGKILL 신호는 프로세스의 자식 프로세스로 전파 sleep되지 않으므로 종료되지도 않습니다.

nohupSIGHUP 신호에 영향을받지 않는 프로세스를 시작합니다. SIGHUP 신호를 수신하면 프로세스가 중단되는 것을 방지합니다.이 경우 옵션이 설정되고 쉘이 종료 bash된 경우 대화식 로그인 인스턴스 가이를 수신 할 수 있습니다 huponexit. 따라서 기술적으로 unset 옵션 nohup을 사용하여 대화식 로그인 bash인스턴스 에서 프로세스를 시작하면 huponexitSIGHUP 신호 수신시 프로세스가 중단되는 것을 막을 수 있지만 쉘에서 나가거나 로그 아웃하면 SIGHUP되지 않습니다.

그러나 일반적으로 nohup상위 쉘에서 SIGHUP 신호가 들어오는 것을 방지해야하는 kill -9경우 상위 메소드를 하위 메소드보다 선호하는 이유는 없습니다 nohup. 대신에 반대가되어야합니다.

kill -9메소드를 사용하여 부모를 종료해도 부모가 정상적으로 종료 될 가능성은 없지만, nohup메소드를 사용하여 자식을 시작하면 SIGHUP와 같은 다른 신호로 부모를 종료 할 수 있습니다 (상황에 맞는 예를 만들기 위해) )를 사용하기 시작한 아이 중 하나가 nohup정상적으로 종료됩니다.


즉, 백그라운드에 배치 된 스크립트가있는 경우 부모 프로세스 (예 : 셸)를 종료해도 여전히 실행 중입니다. 그 스크립트를 죽이는 방법은 무엇입니까?
Sergiy Kolodyazhnyy

@Serg PID가 있다면 단순히 PID를 죽이십시오. PID를 저장하지 않았지만 그의 이름으로 프로세스를 식별 할 수있는 경우 프로세스를 ps -e | grep processPID와 함께 나열해야합니다 (또는 pgrep -x process단일 프로세스와 일치하지 않고 미등록 된 것들과 일치하는 것이 더 좋습니다 ). 문제는이 프로세스를 종료 할 때와 것입니다 kill -9그 자식이 소유 얻을 upstart, 따라서 원래의 PPID가 손실되고 자신의 PPID는 그들이 인식 할 수없는 (AFAIK)하지만 자신의 이름이나 PID에 대한 제작, 신출내기의 PID로 변경
코스

@kos 어떤 조건 nohup에서 부모 프로세스로부터 SIGHUP 신호를 수신 할 때 프로세스가 중단되는 것을 막을 수 있습니까? 에 의해 백그라운드에서 프로세스를 실행하려고합니다 (PuTTY SSH 셸 터미널) nohup <command> <arg> &. PuTTY X버튼 을 클릭하여 로그 아웃하면 백그라운드 프로세스가 즉시 종료됩니다. exitPuTTY SSH 셸 터미널 에 입력하여 로그 아웃 하면 프로세스가 백그라운드에서 계속 실행됩니다.
userpal

3

bash기본적으로 종료 할 때 HUP 신호를 하위 프로세스로 보내지 않습니다 . 더 자세히 설명하면 (@kos 덕분에) 비 로그인 쉘 에는 적용되지 않습니다 .

옵션을 설정하면 로그인 쉘에 대해 bash를 구성 할 수 있습니다 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 신호를 수신했으며 요청에 따라 종료되었습니다.


@kos --- 그래, 당신은 ... 왜 내가하면 잘하지만 살아남? 공지 사항 나는 경우 그 과정이 됩니다 종료합니다. 그리고 설정 하더라도 살아남습니다. 혼란스러워 ... (나는 더 잘 이해하고 망설임을 수정하려고 노력할 것이고 그렇지 않으면 그것을 삭제할 것이다). sleep 1000 & ; exitsleepkill -HUPsleephuponexitsleep
Rmano

2

sleep이런 식으로 살아남을 수 있다면 nohup명령 대신이 방법을 사용할 수 있습니까?

kill -9실제로 사람이 가야 할 길이 아닙니다. TV에서 총을 쏘아서 끄는 것과 같습니다. 코미디 구성 요소 외에는 이점이 없습니다. 프로세스는 catch하거나 무시할 수 없습니다 SIGKILL. 프로세스에서 수행중인 작업을 완료하고 정리할 기회를 제공하지 않으면 손상된 파일 (또는 다른 상태)이 그대로 남아 다시 시작할 수 없게됩니다. kill -9아무것도 작동하지 않을 때 마지막 희망입니다.


로그 아웃하고 터미널을 닫을 때 절전 프로세스가 지속될 수있는 이유는 무엇입니까? 내 생각에, 로그 아웃하면 데몬과 nohup 프로그램을 제외한 모든 것이 종료됩니다.

귀하의 경우에 일어나는 일 :

의 부모 프로세스 sleep는 현재 실행중인 bash쉘입니다. 당신은 때 kill -9그 bash는, bash는 과정은을 보낼 수있는 기회하지가 SIGHUP있기 때문에, 자식 프로세스의에 SIGKILL(로 전송되는 kill -9과정에 의해 잡을되지 않습니다). 절전 프로세스가 계속 실행됩니다. 수면은 이제 고아 과정 이되었습니다 .

init (PID 1) 프로세스는 reparenting이라는 메커니즘을 수행합니다. 즉, init 프로세스가 이제 고아 프로세스의 부모가됩니다. init는 예외입니다. 프로세스는 원래 부모 프로세스를 잃은 프로세스를 수집 할 때 자식 프로세스가 될 수 있습니다. Btw : sshd"백그라운드로 갈 때" 와 같은 데몬 이이를 수행합니다.

그렇게하지 않으면 고아 프로세스는 나중에 (완료되면) 좀비 프로세스가됩니다. 이것은 waitpid()호출되지 않은 경우에 발생합니다 (해당 프로세스가 종료 될 때 완전히 채워질 수없는 상위 프로세스의 책임). waitpid()좀비 자녀를 피하기 위해 특정 간격으로 init를 호출합니다 .


이 과정은 같은 정중 한 신호로도 살아남은 TERM또는HUP
heemayl

@heemayl HUP는 쉘 구성에 따라 다릅니다 huponext. TERM은 수면이 끝날 때까지 기다립니다. OPs sleep 명령의 경우 수천 년이 될 것입니다 =)
혼돈

1

&백그라운드에서 프로세스를 시작합니다. 를 입력 ps -ef하면 수면의 부모 프로세스 ID (PPID)가 배쉬임을 알 수 있습니다. 그런 다음 로그 아웃하고 다시 로그인하십시오. 로그 아웃 한 후에도 프로세스가 계속 실행됩니다. 두 번째로 로그인 한 후 ps -ef다시 실행 하십시오. 이제 수면 프로세스의 부모가 ID가 "1"인 프로세스임을 알 수 있습니다. 그것은 모든 프로세스의 부모 인 init입니다.


0

를 사용 &하면 프로그램이 백그라운드로 실행됩니다. 백그라운드에서 bgcommand를 사용하여 프로그램을 확인하고 프로그램 을 포 그라운드로 다시 실행하려면을 실행하십시오 fg.

예, 메인 터미널이 종료 된 경우에도 프로그램을 계속 실행하는 방법은 여러 가지가 있습니다.


감사. bash의 맨 페이지는 약간 혼란 스럽습니다. "종료하기 전에 대화식 쉘은 SIGHUP을 모든 작업에 재전송하고 실행 중이거나 중지되었습니다."그러나 실제로 쉘은 SIGHUP을 포 그라운드 작업으로 만 보냅니다 . 백그라운드 프로세스는 SIGHUP 신호를받을 기회가 없습니다 ( 'huponexit'쉘 옵션을 변경하지 않는 한)
tom_cat

@ kos 아마 당신이 맞을 것입니다. 이 게시물에서 위의 결론을 얻 습니다. stackoverflow.com/questions/4298741/… 이제 더 혼란스러워졌습니다.
tom_cat

@tom_cat 이것으로 다시 두 번 생각하면 , 포 그라운드 프로세스가 실행 중일 때 쉘이 종료 될 수있는 경우는 없으며 SIGHUPped 또는 무언가가 될 수 있지만 종료 되지는 않습니다 . 맞습니다. 백그라운드 프로세스에만 적용됩니다. 그 반대의 의미는 없기 때문입니다. 그러나 추가 연구를 통해을 huponexit통해 얻은 쉘과 같은 로그인 쉘에서만 작동합니다 (예 :을 통해 얻은 쉘 ssh에서는 안 됨 gnome-terminal)
kos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.