저는 프로세스 관리를 위해 쉘 스크립트를 사용하는 방법을 조사해 왔으며 이것이 올바르게 수행되었는지 확인하는 것이 얼마나 어려운지 깨닫게 되었습니다.
예를 들어, 프로그램의 PID를 파일에 기록하고 wait
맨 위에 놓은 다음 프로그램이 종료된 후 PID 파일을 정리할 수 있습니다.
kill
예를 들어, init 스크립트에서 이 데몬을 사용하려는 경우 다음을 수행하는 것을 고려할 수 있습니다.
do_stop() {
kill $(</var/run/program.pid)
}
이것은 분명히 작동하지 않습니다. PID를 얻고 종료 신호를 보내는 사이에 다른 프로세스가 종료되어 그 자리를 대신했을 수 있습니다.
올바른 접근 방법은 프로그램의 상위 프로그램에서 IPC를 사용하여 하위 프로그램에 종료 신호를 보내는 것 같습니다. 이렇게 하면 해당 프로세스의 PID가 다른 프로세스에서 재사용되지 않습니다.
나는 가능한 한 정확한 내 자신의 초기화 스크립트를 작성하려고 노력해 왔습니다. 이러한 맥락에서 나는 NRPE에 대한 기사를 작성해 왔습니다. 불행하게도 NRPE는 데몬화되어 있고 init와의 연결이 끊어져 있어 wait
사용할 수 없습니다. 대신 나는 다음과 같은 해결책을 생각해 냈습니다.
do_stop() {
echo "Stopping (sending SIGTERM to) nrpe"
pkill -u nrpe || { echo >&2 "nrpe isn't running"; exit 1; }
}
사용자가 실행하는 유일한 프로세스 nrpe
는 NRPE 자체입니다. 이는 시스템이 내 통제하에 있다는 점을 고려하면 비교적 합리적인 솔루션이라고 생각합니다.
제가 궁금한 것은 원자성 pkill
(이것이 맞는 단어라면)입니다. pkill
다음 단계를 따른다고 가정합니다 .
- 프로세스 표준 매개변수를 구문 분석한 후 프로세스 테이블에서 PID를 찾습니다.
SIGTERM
획득한 PID로 전송 (기본값)
pkill -u nrpe
1단계에서 주어진 PID가 42라고 가정합니다 . nrpe
2단계가 발생하기 전에 프로세스가 종료되고 그 자리에 다른 프로세스가 생성될 수 있습니까 ?
답변1
(작은!) 원자성 문제가 있다고 의심하는 것이 옳습니다.
어떤 방법을 사용하든 시스템 표준 유틸리티(예: 사용자 ID start-stop-daemon
로 쿼리하고 종료하기 위해 직접 생성한 PID 파일 pkill
, 실행 가능한 바이너리 또는 기타 수단)인지 여부에 관계없이 원하는 조회 프로세스 사이에는 항상 공백이 있습니다. 프로세스를 종료하고 프로세스 ID를 시스템 kill
호출에 제공하여 신호를 보냅니다.
기본적으로는 걱정하지 않으셔도 됩니다. 문제가 있어서,둘 다다음이 발생해야 합니다.
- 대상 프로세스는 프로세스 ID를 식별하는 시간과 실제로 종료하는 시간 사이에 종료됩니다.
- 새로 생성된 프로세스의 프로세스 ID는 방금 비워진 프로세스 ID를 재사용하기 위해 동일한 간격 내에서 순환되어야 합니다.
이것은 정말 가능성이 낮습니다.
당신이 보고 있는 특정 상황에서는 실제로 이 상황으로부터 자신을 보호할 수 있는 방법이 있다는 점에 유의하십시오. 사용자가 실행하는 유일한 프로세스 는 NRPE 자체이므로 nrpe
명령을 실행하기 전에 사용자로 전환하는 경우가 거의 없습니다 nrpe
.root
kill
노력하다다른 것에 속하지만 권한이 없는 불쌍하고 무고한 프로세스를 죽이는 것은 아무런 효과가 없습니다.