bash가 SIGTERM을 무시하는 이유는 무엇입니까?

bash가 SIGTERM을 무시하는 이유는 무엇입니까?

빨리 로그아웃하고 싶을 때 가끔 이렇게 합니다 kill -15 -1. bash가 SIGTERM을 무시한다는 것을 알았습니다.

나는 알고 싶다이 bash 동작의 이유는 무엇입니까?

정당한 이유 없이 SIGTERM을 무시하는 것은 UNIX와 매우 유사하지 않습니까?

고쳐 쓰다:

모든 사람에게 동일한(없음) 효과가 있습니다.

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

업데이트 2:

~에서남자 난교:

Bash가 대화형일 때 트랩 없이 SIGTERM을 무시합니다.

그래서 이것은 의도적인 것입니다. 그런데 왜?

답변1

우선, 이것은 bash에만 국한되지 않습니다. ATT ksh, dash 및 zsh는 동일한 방식으로 작동합니다. 명령줄 편집 중에 SIGTERM 및 SIGQUIT를 무시합니다. mksh의 경우 종료되지 않지만 SIGINT로 처리됩니다.

ksh 매뉴얼과 bash 매뉴얼은 모두 다음 용어로 SIGTERM을 무시하는 것을 정당화합니다.

이렇게 하면 kill 0대화형 쉘이 종료되지 않습니다.

kill 0모든 프로세스 종료프로세스 그룹쉘은 1에 위치합니다. 간단히 말해서, 프로세스 그룹은 터미널의 포그라운드에서 실행 중이거나 백그라운드에 작업이 있거나 보류 중인 모든 프로세스로 구성됩니다.

보다 정확하게는 이것이 현대 껍질에서 일어나는 일입니다.직업 통제. 이러한 쉘에서는 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. 어쨌든 꽤 위험한 명령입니다.

1 일반적인 쉘 매뉴얼에는 이에 대한 언급이 없는 것 같습니다. 이는 기본 시스템 호출의 기능입니다. 에서 명시적으로 언급됨POSIX 사양.
²오늘 이렇게 하려면 jobs -l작업 목록 보기 및 해당 프로세스 그룹 ID를 실행한 다음 kill -123 -456 …프로세스 그룹을 종료하세요.

답변2

이것은 귀하의 질문에 대한 답변이 될 수 있습니다:

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를 사용하여 수신하지 않도록 표시하십시오. 한숨.

huponexit 쉘 옵션이 shopt를 사용하여 설정된 경우(Shopt 내장 참조) Bash는 대화형 로그인 쉘이 종료될 때 모든 작업에 SIGHUP을 보냅니다.

Bash가 명령이 완료되기를 기다리고 트랩이 설정되었다는 신호를 받으면 명령이 완료될 때까지 트랩이 실행되지 않습니다. Bash가 wait 내장 함수를 통해 비동기 명령을 기다릴 때 트랩 세트가 있는 신호를 수신하면 wait 내장 함수가 128보다 큰 종료 상태로 즉시 반환된 다음 즉시 트랩을 실행하게 됩니다.

원천:GNU 배쉬 매뉴얼

관련 정보