최근에 쉘 스크립트에서 이 문제가 발생했습니다.
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
(예:파이썬 예제).