`kill -0`은 무엇을 합니까?

`kill -0`은 무엇을 합니까?

최근에 쉘 스크립트에서 이 문제가 발생했습니다.

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

kill -0 ...효과 는 무엇입니까 ?

답변1

이것은 수집하기가 약간 어렵지만 다음 2개의 매뉴얼 페이지를 보면 다음 설명을 볼 수 있습니다.

죽이다(1)

$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...

죽이다(2)

$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; 
this can be used to check for the existence of a process ID or process 
group ID.
...

따라서 신호 0은 실제로 프로세스의 PID에 아무 것도 보내지 않지만 그렇게 할 권한이 있는지 확인합니다.

이것이 어디에 유용할까요?

이를 확인할 수 있는 한 가지 확실한 장소는 실행 중인 프로세스에 신호를 보내 권한이 있는지 확인하려는 경우입니다 kill. kill원하는 실제 신호를 보내기 전에 kill -0 <PID>먼저 허용되는지 확인하기 위해 수표를 래핑하여 확인할 수 있습니다 .

다음과 같이 프로세스가 루트에 의해 실행되고 있다고 가정합니다.

$ sudo sleep 2500 &
[1] 15693

이제 다른 창에서 이 명령을 실행하면 PID가 실행 중인지 확인할 수 있습니다.

$ pgrep sleep
15693

이제 이 명령을 시도하여 PID 신호를 보낼 권한이 있는지 확인해 보겠습니다 kill.

$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!

따라서 작동하지만 출력에는 kill권한이 없다는 명령의 메시지가 누출됩니다. 별거 아닙니다. STDERR을 캡처하여 /dev/null.

$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!

완전한 예

그러면 우리는 다음과 같이 할 수 있습니다 killer.bash:

#!/bin/bash

PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then 
  echo "you don't have permissions to kill PID:$PID"
  exit 1
fi

kill -9 $PID

이제 루트가 아닌 사용자로 위 명령을 실행하면 다음과 같습니다.

$ ~/killer.bash 
you don't have permissions to kill PID:15693

$ echo $?
1

그러나 루트로 실행하는 경우:

$ sudo ~/killer.bash 

$ echo $?
0

$ pgrep sleep
$

답변2

kill -0(또는 보다 이식성이 뛰어난 POSIX 변형 kill -s 0)은 신호를 보내는 작업을 수행하지만 실제로 신호를 보내지는 않습니다. 그 특징 중 하나는저수준 C API생각하다쉘 명령직접적인 방법으로 노출됩니다.

kill -s 0 -- "$pid"따라서 주어진 PID(또는 음수인 경우 PGID)를 사용하여 실행 중인 프로세스가 있는지 여부 $pid와 현재 프로세스 $pid에 신호를 보낼 수 있는 권한이 있는지 여부(또는 음수인 경우 프로세스 그룹의 모든 프로세스)를 테스트합니다. 주로 프로세스(또는 프로세스 그룹)가 살아 있는지 테스트하는 방법입니다.

예상되는 PID 및 권한을 가진 실행 중인 프로세스가 있더라도 이것이 반드시 예상한 프로세스는 아니라는 점을 명심하십시오. 예상한 프로세스가 조기 종료되어 관련 없는 프로세스에 해당 PID가 재사용될 수 있습니다. 프로세스를 모니터링하는 올바른 방법은 상위 프로세스를 수행하도록 하는 것입니다. 프로세스의 PID는 상위 프로세스가 종료되었음을 확인할 때까지 재사용되지 않습니다.좀비존재), 프로세스의 상위 프로세스는 PID를 통해 하위 프로세스를 안정적으로 식별할 수 있습니다.

답변3

kill -0 $pid프로세스가 존재하는지 여부를 알려줍니다 $pid.

단편적으로

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

... do something ...저장된 PID가 있는 프로세스가 실행 중인 경우 블록이 실행되고 /path/to/file.pid, 코드 조각이 루트로 실행되지 않는 한 PID가 동일한 사용자로 실행되는 경우에도 실행됩니다.

POSIX 표준은 신호가 수행하는 작업을 지정합니다 0.

sig가 0(널 신호)이면 오류 검사가 수행되지만 실제로 신호가 전송되지 않습니다. 널 신호를 사용하여 pid의 유효성을 확인할 수 있습니다.

(킬(3p), POSIX.1-2008 - POSIX.1-2001과 유사한 표현)

POSIX는 명령줄 kill -0스타일 kill -s 0(죽이기(1p)).

Kill 시스템 호출 인터페이스와 비교하여 이 kill명령은 다른 사용자(일반 사용자)가 소유한 PID가 존재하는지 여부를 안정적으로 확인하는 데 사용할 수 없습니다. 예:

$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1

그리고

$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1

kill 시스템 호출이 호출될 때의 값을 보면 이러한 경우를 확실하게 구분할 수 있습니다 errno(예:파이썬 예제).

관련 정보