서비스에서 생성된 모든 하위 프로세스를 중지하는 방법

서비스에서 생성된 모든 하위 프로세스를 중지하는 방법

다음 구성으로 Ubuntu에서 실행되는 서비스가 있습니다.

#/etc/init/my_service.conf

start on (local-filesystems and net-device-up IFACE=eth1)

respawn

exec python -u /opt/XYZ/my_prog.py 2>&1 \
                 | logger -t my_prog.py

를 사용하여 서비스를 중지하면 sudo service my_service stopPython 프로세스가 종료되지 않습니다. 상위 프로세스를 종료해도 killPython 프로세스는 종료되지 않습니다.

서비스를 완전히 중지하려면 어떻게 해야 합니까(즉, 모든 하위 프로세스가 종료됩니까?) 이상적으로는 위의 구성 파일을 수정하지 않는 것이 좋습니다.

답변1

이상적으로는 위의 구성 파일을 수정하지 않는 것이 좋습니다.

힘든! 그렇게 하는 것이 옳은 일입니다.

exec로 변경 script하고 파이프라인의 일부로 분기된 하위 프로세스에서 해당 Python 프로그램 실행을 중지해야 합니다. 이 ServerFault 답변임베디드 쉘 스크립트에서 이를 수행하는 방법을 설명합니다. 마지막 줄에 있는 스크립트를 한 번만 변경하겠습니다.

exec python -u /opt/XYZ/my_prog.py 2>&1

결국 표준 오류도 기록하지 않을 이유가 없습니다.

expect daemon에서 으로 전환하는 등 분기에 대처하기 위한 더욱 복잡한 선회는 systemd올바른 일이 해야 할 요점을 놓칩니다.데몬의 분기를 중지합니다.. 현재의 소란 속에서 좋은 점 하나가 있다면 IBM이 1995년에 작성하고 권장한 내용이 지난 몇 년 동안 옳았다는 지속적인 확인이 있다는 것입니다.

'라는 생각에 익숙해지세요.체인 로딩데몬. 이러한 작업을 간단하게 만들어주는 도구 세트가 많이 있습니다. 쉘 스크립트도 사용하지 않는다는 생각에 익숙해지십시오. 쉘의 오버헤드를 제거하기 위해 특별히 이 작업을 위해 설계된 많은 도구 세트가 있습니다(이는 우분투 세계에서 알려진 좋은 아이디어입니다.).

예: ServerFault 응답의 셸 명령은 다음을 사용하는 스크립트로 대체될 수 있습니다.Laurent Bercot의 execline도구이는 서브쉘과 연결되지 않은 FIFO 없이 바로 이 작업을 수행할 수 있도록 설계되었습니다.

#!/command/execlineb -PW
pipeline -w {
    logger -t my_prog.py
} 
fdmove -c 2 1 
python -u /opt/XYZ/my_prog.py

그러면 간단히 말해서

exec /foo/this_execlineb_script

와 함께nosh도구 세트, 이는 유사하게 다음을 포함하는 스크립트가 됩니다.

#!/usr/local/bin/nosh
pipe 
fdmove -c 2 1 
python -u /opt/XYZ/my_prog.py | logger -t my_prog.py

또는 Upstart 작업 정의에 직접 이 스탠자를 포함할 수도 있습니다(Upstart가 셸을 생성하지 않도록 셸 메타 문자를 피하는 트릭을 사용).

exec /usr/local/bin/exec pipe --separator SPLIT fdmove -c 2 1 python -u /opt/XYZ/my_prog.py SPLIT logger -t my_prog.py

추가 읽기

답변2

GNU/Linux에서는 일반적으로 서비스와 서비스가 생성한 모든 하위 프로세스를 중지할 수 있는 방법이 없습니다. 하위 프로세스가 PPID(상위 프로세스 ID)를 변경할 수 있기 때문입니다. 알 수 있는 유일한 방법은 다음과 같습니다.추적하다시스템은 프로세스가 생성될 때 프로세스를 생성하고 이러한 프로세스의 목록을 유지하도록 호출합니다.

Ubuntu 초기화 시스템은 upstart이 작업을 수행하지 않습니다. 따라서 귀하의 질문에 대한 답변은 다음과 같습니다.그것은 불가능-- 우분투에서는 -- 다음 없이:

  1. 해당 스크립트를 수정합니다.
  2. 해당 프로세스에 의해 생성된 프로세스 ID를 정확히 파악합니다.
  3. 해당 프로세스 ID를 수동으로 추적합니다.
  4. 그들을 개별적으로 죽이는 것.

이것이 바로 Linux 배포판을 실행해야 하는 이유입니다.체계화된. 보시다시피 체계적으로모든 하위 프로세스를 추적합니다.단 하나의 명령으로 그들 모두를 죽일 수 있습니다. 이것이 GNU/Linux 시스템 관리 방법입니다.해야한다, 그러나 systemd는 매우 새롭고 "여기에서 발명되지 않음"(즉, Canonical이 발명하지 않았음)이기 때문에 Ubuntu는 이를 사용하고 싶어하지 않습니다.

답변3

건너뛰었습니다.예상하다절. 그만큼신생 요리책다음을 지정합니다:

경고

이 스탠자는 매우 중요합니다. 이 섹션을 주의 깊게 읽어보세요!

Upstart는 작업에 속한다고 생각되는 프로세스 ID를 추적합니다. 작업이 인스턴스 스탠자를 지정한 경우 Upstart는 해당 작업의 각 고유 인스턴스에 대한 PID를 추적합니다.

예상 스탠자를 지정하지 않으면 Upstart는 exec 또는 스크립트 스탠자에서 실행하는 첫 번째 PID의 수명 주기를 추적합니다. 그러나 대부분의 Unix 서비스는 "데몬화"됩니다. 즉, 초기 프로세스의 하위 프로세스인 새로운 프로세스(fork(2) 사용)를 생성한다는 의미입니다. 종종 서비스는 초기 프로세스와 아무런 관련이 없는지 확인하기 위해 "이중 포크"됩니다. (추가적인 이점이 없기 때문에 어떤 서비스도 처음에 두 번 이상 포크되지 않습니다.)

이 경우 Upstart에는 이를 추적할 수 있는 방법이 있어야 합니다. 따라서 Expect Fork를 사용하거나 Upstart가 ptrace(2)를 사용하여 "포크 수 계산"을 허용하는 데몬을 사용할 수 있습니다.

Upstart가 작업에 대한 최종 프로세스 ID를 결정하도록 허용하려면 해당 프로세스가 분기(2)를 호출하는 횟수를 알아야 합니다. Upstart 자체는 이 질문에 대한 답을 알 수 없습니다. 데몬이 실행되면 자체적으로 여러 번 포크될 수 있는 여러 "작업자" 프로세스를 포크할 수 있기 때문입니다. Upstart는 이 경우 어떤 PID가 "마스터"인지 알 것으로 기대할 수 없습니다. 작업자 프로세스가 생성될 것인지 여부는 물론 프로세스가 처음에 몇 번 분기될 것인지도 모르기 때문입니다. 따라서 Upstart에게 어느 PID가 "마스터"인지 또는 상위 PID인지 알려줄 필요가 있습니다. 이는 Expect 스탠자를 사용하여 달성됩니다.

|사용 중인 파이프가 하위 프로세스를 생성하기 때문에 이것이 필요합니다 . 책에서 만나보실 수 있어요고급 리눅스 프로그래밍이에 대한 간략한 소개는 다음과 같습니다.

예를 들어, 이 쉘 명령은 쉘이 두 개의 하위 프로세스를 생성하도록 합니다.ㅋㅋㅋ그리고 하나는더 적은:

 $ ls | less

내가 모르는 것은 이것이 하나 또는 두 개의 포크를 의미하는지 여부이므로 라인을 수정하여 실험해 보겠습니다.부활하다코드에서

 expect fork
 respawn

또는

 expect daemon
 respawn

나는 이것이 달성될 수 있다고 믿지 않는다오직~와 함께체계화된, 내 로고에는 내가 팬이라는 것이 분명하게 표시되어 있지만체계화된.

관련 정보