하위 프로세스에 있을 때 일부 신호 또는 PID에 의한 종료를 통해 상위 프로세스를 종료하는 올바른 bash 명령/지침은 무엇입니까?
답변1
내가 올바르게 이해했다면 가능한 해결책 중 하나는 trap
쉘 프로세스나 명령을 사용하는 것입니다.
솔루션 1
노트:그것을 사용하는 trap
것은 쉘을 사용할 때만 작동하는 것 같습니다. 예를 들어 터미널에서 명령을 실행하거나 스크립트(예 myscript.sh
: trap
.
예를 살펴보겠습니다:
ps -fH
현재 상위 프로세스( 셸) 에 들어가면 zsh
다음을 얻습니다.
%> ps -fH
#Output:
UID PID PPID C STIME TTY TIME CMD
edgar 17932 24608 0 23:37 pts/2 00:00:00 /bin/zsh
edgar 18001 17932 0 23:38 pts/2 00:00:00 ps -fH
이제 하위 프로세스를 실행 bash
하고 ps -H
다시 입력하겠습니다.
%> bash
(bash shell) %> ps -fH
#Output:
UID PID PPID C STIME TTY TIME CMD
edgar 17932 24608 0 23:37 pts/2 00:00:00 /bin/zsh
edgar 18012 17932 0 23:38 pts/2 00:00:00 bash
edgar 18030 18012 0 23:38 pts/2 00:00:00 ps -fH
보시다시피, bash 쉘의 상위 프로세스에는 zsh
PID가 있습니다 17932
.
특정 프로세스의 PPID를 얻으려면 를 사용해야 합니다 . 예를 들어 현재 프로세스의 상위 프로세스 ID를 ps -o ppid= $SOME_PID
얻으려면 다음을 사용해야 합니다.bash
(bash shell) %> ps -o ppid= 18012
#Output:
17932
아니면 추천할 만한 다른 것이 있나요?
(bash shell) %> ps -o ppid= $$
#Output
17932
$$
현재 실행 중인 프로세스의 프로세스 ID를 가져오고 있습니다. 이 경우에는 bash
.
마지막으로 상위 프로세스(이 경우)를 종료하려면 zsh
다음 명령을 실행해야 합니다.
(bash shell) %> trap "echo Killing parent process $(ps -o ppid= $$); kill -9 $(ps -o ppid= $$)" 0
#Or
(bash shell) %> trap "kill -9 $(ps -o ppid= $$)" 0
이제 입력 exit
하거나 누르면 Ctrl + D상위 프로세스 zsh
도 종료됩니다.
(bash shell) %> exit
#zsh was killed too, so the terminal will show the following output:
Warning: Program '/bin/zsh' crashed
피하기 위해zsh가 충돌했습니다bash
셸을 두 번 실행할 수 있다는 메시지
솔루션 2
이 strace
명령을 사용하면 모든 프로세스에서 작동합니다.
예를 살펴보겠습니다:
백그라운드에서 프로세스를 실행하고 strace
해당 프로세스를 종료할 수 있는 상위 프로세스에 연결합니다.
먼저 쉘에서 bash
실행 하겠습니다.zsh
(zsh shell) %> bash
이제 bash
셸에서 백그라운드에서 프로세스를 실행하겠습니다. 이 예에서는 이 sleep
명령을 사용하여 해당 PPID(상위 프로세스 ID)를 가져옵니다.
(bash shell) %> sleep 60& #sleep 1 minute (in background)
processID=$! #with $! we get the pid of the last executed process, in this case the sleep command
parentID=$(ps -o ppid= $processID)
ps -fH
출력을 살펴보면 다음과 같은 결과를 얻습니다.
UID PID PPID C STIME TTY TIME CMD
edgar 21593 21579 0 00:43 pts/1 00:00:00 /bin/zsh
edgar 22971 21593 0 01:03 pts/1 00:00:00 bash
edgar 23011 22971 0 01:07 pts/1 00:00:00 sleep 60
edgar 23012 22971 0 01:08 pts/1 00:00:00 ps -fH
bash
이제 완료 되면 상위 프로세스를 종료 하려고 합니다 sleep 60
. 이를 위해 다음 명령을 사용합니다 strace -p
.
strace -p $processID ; kill -9 $parentID
strace -p는 PID를 사용하여 프로세스를 연결하는 데 사용됩니다.
프로세스 $processID
(sleep 명령)가 완료되면 kill 명령이 실행되어 $parentID(bash 쉘)를 종료합니다.
노트:strace
신호를 받았을 때 명령을 실행할 수 있는지 잘 모르겠습니다 . 이 방법은 프로세스가 완료된 후에만 작동합니다.
위 명령에 대한 설명
ps의 사용
에 따르면 ps --help
:
-f -- 전체 목록
--forest -H -- 프로세스 계층 구조 표시
ps -f
출력에는 .단지 사용하는 것보다 더 많은 열이 표시됩니다 ps
. 나는 모든 과정을 ps -f
이해 하곤 했다 PPID
.
도움말에 표시된 대로 ps -H
(를 사용할 수도 있음 )을 사용하면 프로세스 계층 구조가 표시됩니다. 즉, 특정 프로세스의 각 하위 프로세스가 특별한 형식으로 표시됩니다. ps --forest
실행하면 ps -H
다음과 같은 결과를 얻습니다.
PID TTY TIME CMD
2872 pts/1 00:00:00 zsh
3771 pts/1 00:00:00 bash
7259 pts/1 00:00:00 ps
ps
이것이 의 자식 프로세스이고 bash
, 이것이 의 프로세스라는 것을 알 수 있습니다 zsh
.
대신 다음을 실행할 수도 있습니다 ps f
(BSD 구문) ps -H
.
%> ps f
#Output:
PID TTY STAT TIME COMMAND
2872 pts/1 Ss 0:00 /bin/zsh
3771 pts/1 S 0:00 \_ bash
7495 pts/1 R+ 0:00 \_ ps f
트랩의 사용
의 구문은 trap
다음과 같습니다 trap 'commands' SIGNAL
. 이는 프로세스가 특정 메시지를 받으면 SIGNAL
실행된다는 의미입니다. 더 나은 설명을 위해 commands
다음을 입력할 수 있습니다 .man trap
조건은 기본 정의 볼륨에 정의된 <signal.h> 헤더의 신호 이름 테이블에 나열된 대로 EXIT, 0(EXIT와 동일) 또는 기호 이름(SIG 접두사 없이)을 사용하여 지정된 신호일 수 있습니다. POSIX.1‐2017.
...
XSI 호환 시스템에서는 다음 신호 이름에 해당하는 조건에서 디지털 신호 번호를 사용할 수도 있습니다.
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM
trap 'commands' 0
따라서 쉘을 사용하는 경우 'commands'
쉘을 종료할 때 트랩에 지정된 내용이 실행됩니다.
예를 들어, bash 쉘은 다음 코드를 수신 echo
하면 실행됩니다.SIGINT
(bash_shell) %> echo Bash PID: $$
#Output:
Bash PID: 8529
(bash_shell) %> trap 'echo Bash got SIGINT signal' 2
(bash_shell) %> kill -SIGINT 8529
#Output:
^CBash got SIGINT signal
bash 쉘에서 kill -SIGINT 8529
다음을 누를 수도 있습니다.Ctrl+C
노트:일부 신호 에서는 작동하지 않을 수 있습니다 trap
(SIGKILL을 사용하여 테스트했는데 작동하지 않습니다).
죽여 사용하다
man kill
또는 를 사용하면 man 1p kill
명령에 대한 자세한 설명을 얻을 수 있습니다.
Kill -s 신호 이름 pid
Kill -l [종료 상태]
kill[-signal_name] pid
Kill [-signal_number] pid ...
-s signal_name
<signal.h> 헤더에 정의된 기호 이름 중 하나를 사용하여 보낼 신호를 지정합니다. signal_name 값은 SIG 접두사 없이 대소문자를 구분하지 않고 식별되어야 합니다. 또한 신호 값이 0임을 나타내는 기호 이름 0이 인식되어야 합니다. SIGTERM 대신 해당 신호를 보내야 합니다.
-signal_name
은 -s signal_name과 동일합니다.-signal_number는
kill()에 대한 유효한 호출에서 SIGTERM 대신 사용할 신호를 나타내는 음이 아닌 십진수 signal_number를 지정합니다. 사용된 정수 값과 시그니처 값 간의 대응 관계는 아래 표에 나와 있습니다. 다음 이외의 signal_number를 지정하는 효과는 정의되지 않습니다.
0 0
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM
따라서 명령은 kill -9 8990
와 동일합니다 kill -SIGKILL 8990
. SIGKILL
프로세스로 전송되면 프로세스가 종료/종료됩니다.