bash는 왜 SIGTERM을 무시합니까?


10

가끔 빨리 로그 아웃하고 싶을 때가 kill -15 -1있습니다. bash가 SIGTERM을 무시하고 있음을 알았습니다.

그런 배쉬 행동의 근거가 무엇인지 궁금 합니다 .

타당한 이유없이 SIGTERM을 무시하는 것은 유닉스가 아닙니다. 그렇지 않습니까?

최신 정보:

모두에게 동일한 (아니오) 영향 :

$ kill -TERM $$
$ type kill
kill is a shell builtin
$ command kill -TERM $$
$ /bin/kill -TERM $$

UPDATE2 :

에서 남자 bash는 :

bash가 대화식 일 때 트랩이 없으면 SIGTERM을 무시합니다.

따라서 일부러 완료되었습니다. 그런데 왜?


어떤 킬을 사용하고 있습니까? /bin/kill아니면 껍질 내장? 후자라면, 쉘이 자체 내장으로 죽지 않을 것이라고 생각합니다.
terdon

@ terdon : 내장을 사용했지만 그것이 자기를 죽이지 않는 이유라고 생각하지 않습니다.
Michał Šrajer 12

1
빠르게 로그 아웃하려면 Ctrl + d
YoMismo

1
@YoMismo : "X 세션에서 로그 아웃"
Michał Šrajer

2
@ MichałŠrajer : Ctrl-Alt-Backspace는 Xorg에서 나를 위해 이것을 수행합니다 ...하지만 xorg.conf에서 활성화해야 할 수도 있습니다.
Laszlo Valko 2019

답변:


10

첫째, 이것은 bash에만 국한되지 않습니다. ATT ksh, dash 및 zsh는 동일한 방식으로 작동합니다. 명령 행 편집 중에 SIGTERM 및 SIGQUIT를 무시합니다. mksh는 종료하지 않고 SIGINT처럼 취급합니다.

ksh 매뉴얼과 bash 매뉴얼은 다음과 같은 용어로 SIGTERM을 무시합니다.

그 때문에 kill 0대화 형 쉘을 죽이지 않는다

kill 0쉘이 있는 프로세스 그룹의 모든 프로세스를 중단시킵니다 ¹. 간단히 말해서 프로세스 그룹은 터미널의 포 그라운드에서 실행중인 모든 프로세스 또는 백그라운드 또는 일시 중단 된 작업의 모든 프로세스로 구성됩니다.

보다 정확하게는 이것이 작업 제어 기능이 있는 현대 쉘에서 발생하는 입니다. 이러한 셸에서는 kill 0셸이 자체 프로세스 그룹에 있으므로 유용하지 않습니다. 이전 쉘 (또는 이후의 현대 쉘 set +m)은 백그라운드 명령에 대한 프로세스 그룹을 작성하지 않았습니다. 따라서이 명령 kill 0을 사용하여 로그 아웃하지 않고 모든 백그라운드 명령을 강제 종료 할 수 있습니다 .² 따라서 kill 0근거는 오늘날 더 이상 정당화되지 않지만 이전 버전과의 호환성을 위해 유지되는 오래된 명령 처럼 보입니다.

그러나 쉘 면역을 만드는 것이 유용한 다른 유사한 상황이 있습니다. 터미널 호핑 프로세스가 있고 로그 아웃하지 않고 종료하려는 경우를 고려하십시오. 많은 시스템에는 pkill터미널에서 실행중인 프로세스를 종료 할 수 있는 도구 가 있습니다. 신호를 무시하는 쉘을 제외하고 현재 터미널에서 실행중인 모든 프로세스를 실행 pkill -t $TTY하거나 종료 pkill -QUIT -t $TTY할 수 있습니다 .

쉘은 일반적으로 사용자가 (같은 명령으로 종료 할 때 어느 사라질 exit또는 logout말단 신호 입력의 단부 (사용자가 누름으로써이 발생할 수있는 경우), 또는 Ctrl+를 D) 또는 완전히 사라진다. 이 마지막 경우, 쉘은 SIGHUP 신호를 수신하며,이를 무시하지 않습니다.

X 세션에서 로그 아웃하는 유스 케이스의 경우 kill -15 -1터미널 에뮬레이터를 종료하여 쉘이 SIGHUP을 수신하게하므로이를 수행합니다. 실제로 X 서버를 죽일 수는 있지만 프로세스 ID를 찾아야합니다. 동일한 명령이 텍스트 세션에서 작동하도록하려면을 사용할 수 있습니다 kill -15 -1; exit. 그것은 어쨌든 당신의 손끝에 가지고있는 매우 위험한 명령입니다.

¹ 이것은 쉘 매뉴얼에서 일반적으로 언급되지 않은 것 같습니다. 기본 시스템 호출의 기능입니다. POSIX 사양에 명시 적으로 언급되어 있습니다.
² 요즘에는 jobs -l프로세스 그룹 ID가있는 작업 목록을보고 프로세스 그룹을 종료 kill -123 -456 …하기 위해 실행됩니다.


5

이것은 당신의 질문에 대답 할 수 있습니다 :

Bash가 대화식 일 때 트랩이 없으면 SIGTERM을 무시하고 ( 'kill 0'이 대화식 쉘을 종료하지 않음) SIGINT가 포착되어 처리됩니다 (대기 내장 대기 가능). Bash가 SIGINT를 수신하면 실행 루프가 중단됩니다. 모든 경우에 Bash는 SIGQUIT를 무시합니다. 작업 제어가 유효하면 (작업 제어 참조) Bash는 SIGTTIN, SIGTTOU 및 SIGTSTP를 무시합니다.

Bash에 의해 시작된 내장되지 않은 명령에는 신호 핸들러가 상위에서 쉘에 의해 상속 된 값으로 설정되어 있습니다. 작업 제어가 유효하지 않으면 비동기 명령은 상속 된 핸들러 외에도 SIGINT 및 SIGQUIT를 무시합니다. 명령 대체의 결과로 실행되는 명령은 키보드 생성 작업 제어 신호 SIGTTIN, SIGTTOU 및 SIGTSTP를 무시합니다.

SIGHUP을 받으면 기본적으로 쉘이 종료됩니다. 종료하기 전에 대화식 쉘은 SIGHUP을 실행 또는 중지 된 모든 작업으로 다시 보냅니다. 중지 된 작업은 SIGHUP을 수신 할 수 있도록 SIGCONT로 전송됩니다. 쉘이 SIGHUP 신호를 특정 작업으로 전송하지 못하게하려면 disown 내장 (작업 제어 내장 참조)이있는 작업 테이블에서 제거하거나 disown -h를 사용하여 SIGHUP을 수신하지 않도록 표시해야합니다.

huponexit 쉘 옵션이 shopt로 설정되면 (Shopt Builtin 참조) Bash는 대화식 로그인 쉘이 종료 될 때 모든 작업에 SIGHUP을 보냅니다.

Bash가 명령이 완료되기를 기다리고 트랩이 설정된 신호를 수신하면 명령이 완료 될 때까지 트랩이 실행되지 않습니다. Bash가 대기 내장을 통해 비동기 명령을 기다리는 경우 트랩이 설정된 신호를 수신하면 대기 내장이 종료 상태가 128보다 큰 상태로 즉시 리턴되어 트랩이 실행 된 직후에 발생합니다.

출처 : GNU Bash 매뉴얼


나는 이것을 update2에서 인용했다. 남자는 배쉬가 그렇게하고 있다고 말하지만 왜 그런 결정을했는지 설명하지 않습니다. 질문이 남아 있습니다-왜?
Michał Šrajer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.