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


61

나는 최근에 쉘 스크립트에서 이것을 발견했다.

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

무엇을 kill -0 ...합니까?


2
당신이 B 차이점에 대한 혼란이 있다면 여기를 참조하십시오 / 배쉬의 w trap명령에서 신호를 0 대 0 kill: 트랩 명령 신호 0은 무엇입니까?
slm

또한 이전 StackOverflow의 질문을 참조하십시오 무엇 kill -0 $pid쉘 스크립트 수행을에를? 뿐만 아니라 실제로 0을 죽이는 것은 무엇입니까? .
Adam Katz

답변:


76

이 글은 조금 다루기가 어렵지만 다음 두 매뉴얼 페이지를 보면 다음과 같은 메모가 표시됩니다.

죽이기 (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
$

9
또한 프로세스가 여전히 활성 상태인지 확인하기 위해 다중 프로세스 스크립트에 사용할 수 있습니다.
prateek61

1
@ slm 좋은 찾기. 스크립트 에서이 논리를 사용하여 작성 중입니다. 감사합니다.
111 ---

12
Prateek61이 옳습니다. pgrep, ps파싱 ​​또는 test -e /proc/$PID휴대용 스크립은 사용할 수 없지만 kill -0어디에서나 작동합니다. 예를 들어 /var/run항목과 같이 부실한 PID가 제공되는 경우 프로세스가 아직 활성 상태인지 확인하는 이식 가능한 방법입니다.
워렌 영

1
PID가 활성 상태인지 여부를 알려주는 것 외에도 다른 UID에 신호를 보낼 수있는 권한이 없기 때문에 (루트가 아닌 경우) PID가 여전히 UID에서 프로세스를 실행 중인지 여부를 효과적으로 알려줍니다. 이로 인해 PID 재사용으로 인한 오 탐지 가능성이 줄어 듭니다.
Barmar

실패 kill -0 $(pgrep sleep)가 반드시 자신의 약함을 의미하는 것은 아니며 sleep명령이 실행 중이 아니 거나 둘 이상의 명령이 있고 죽일 수없는 명령이 있거나 수면 중 하나가 pgrep과 kill 사이에 죽으면 false를 반환 합니다 명령이 실행 중입니다.
Stéphane Chazelas

22

kill -0(또는 이식성이 뛰어난 POSIX 변형 kill -s 0)은 신호를 보내는 동작을 거치지 만 실제로는 신호를 보내지는 않습니다. 쉘 명령 이 직접 노출 하는 것은 기본 C API 의 기능입니다 .

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

예상 PID 및 권한이있는 실행중인 프로세스가 있어도 반드시 예상 한 프로세스는 아닙니다. 예상 한 프로세스가 더 일찍 종료되어 관련 프로세스에 PID가 재사용되었을 수 있습니다. 프로세스를 모니터링하는 올바른 방법은 부모가 처리하도록하는 것입니다. 프로세스의 PID는 부모가 자신의 죽음을인지 할 때까지 재사용되지 않으므로 ( 좀비 가 존재하는 이유 ) 프로세스의 부모는 PID를 통해 자식을 안정적으로 식별 할 수 있습니다.


0

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 (null 신호)이면 오류 검사가 수행되지만 실제로는 신호가 전송되지 않습니다. 널 신호를 사용하여 pid의 유효성을 확인할 수 있습니다.

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

POSIX 모두 지정합니다 kill -0kill -s 0명령 줄 스타일 (죽 (1P)를).

kill syscall 인터페이스와 달리이 kill명령을 사용하여 다른 사용자가 소유 한 PID (일반 사용자)의 존재 여부를 확실하게 확인할 수 없습니다. 예 :

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

vs.

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

kill syscall을 호출 할 때 errno값 (예 : Python Example ) 을 확인하여 이러한 경우를 확실하게 구별 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.