위 명령에 대한 설명

위 명령에 대한 설명

하위 프로세스에 있을 때 일부 신호 또는 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 쉘의 상위 프로세스에는 zshPID가 있습니다 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프로세스로 전송되면 프로세스가 종료/종료됩니다.

관련 정보