우분투 16.04를 실행 중입니다.
이 프로세스 X가 여러 tty에서 실행되고 있습니다. screen 명령을 사용하여 다른 의사 터미널에서 실행하고 crontab에서도 실행합니다.
이 프로그램은 bash 스크립트에서 시작되는 Python 스크립트에서 시작됩니다.
때때로 Python 스크립트는 내가 잡을 수 없는 예외를 발생시키고 프로세스 X를 계속 실행합니다.
Bash 스크립트 끝에서 이 프로세스 X를 종료하고 싶지만 다른 터미널에서 실행 중인 다른 X 프로세스는 종료하지 마세요.
-t 매개변수를 사용하는 다른 터미널과 관련이 없는 X를 처리하기 위해 pgrep을 사용하려고 생각했지만 문서의 구문을 이해할 수 없습니다.
답변1
Python 코드에 대한 새 프로세스 그룹을 시작합니다(사용setsid
유틸리티) 및 시작되는 다른 모든 프로세스(애플리케이션 자체 포함)를 포함하므로 필요한 경우 전체 프로세스 그룹을 종료할 수 있습니다.
이를 수행하려면 다음 구성을 사용할 수 있습니다.
exec 3>&1
pgid=$(exec setsid bash -c 'echo $$; exec >&3-; exec COMMAND...')
COMMAND...
일반적으로 실행하는 명령과 해당 인수는 어디에 있습니까? 작은따옴표 안에 있으며 실행할 명령은 문자열(일반 쉘 표현식이 아님)로 평가될 수 있어야 합니다.
첫 번째 리디렉션에서는 3>&1
표준 출력 설명자를 설명자 3에 복사합니다. 리디렉션은 >&3-
설명자 3을 표준 출력으로 이동합니다.
표준 출력에 기록된 데이터를 실행하고 평가합니다 $(...)
. ...
위에서는 표준 출력을 쉘 변수로 읽었습니다 pgid
.
서브쉘( ...
)은 다음으로 대체되었습니다.setsid
새 세션(프로세스 그룹)에서 해당 인수를 실행하는 유틸리티입니다. 여기서는 실행하고 bash
, 현재 프로세스 PID()를 인쇄하고 $$
, 원래 stdout을 설명자 3에서 뒤로 이동하고, 실행에 필요한 모든 것을 자체적으로 대체합니다 COMMAND...
.
쉘은 실행되는 동안 해당 행을 실행하고 COMMAND...
자체 종료 후에만 다음 행으로 진행합니다.COMMAND...
COMMAND...
가짜 프로세스가 여전히 실행 중이고 이를 종료하고 싶다면 실행하기만 하면 됩니다 .
kill -SIGNAL -$pgid
문제는 어떤 신호를 보낼 것인가이다. KILL
프로세스 그룹의 나머지 프로세스를 즉시 종료하므로 이것이 가장 쉬운 옵션입니다. 그러나 프로세스가 제대로 작동한다면 다음을 수행할 수 있어야 합니다.묻다그들에게 신호를 보내서 그만 두라고 말하십시오 TERM
. 물론 때로는 프로세스가 불안정한 상태에 있어서 반응하지 않아 편집이 TERM
필요할 수도 있습니다 KILL
. 이 문제를 해결하려면 작은 루프를 사용하여 ps
남은 프로세스가 있는지 확인할 수 있습니다.
retries=50
while ((1)); do
# Processes left?
left=$(ps -o pid= -s $pgrp)
[ -n "$left" ] || break
# Ask them to terminate.
kill -TERM $left
# Wait 0.1 seconds.
sleep .1
# Decrement the retry counter.
((--retries > 0)) || break
done
# If there are any processes left in the group,
# send them a KILL signal.
left=$(ps -o pid= -s $pgrp)
[ -n "$left" ] && kill -KILL $left
50회 재시도(각각 0.1초)는 종료 신호를 보내기 전에 최대 5초만 기다린다는 의미입니다. 이는 응용 프로그램과 응용 프로그램이 실행되는 하드웨어 유형에 따라 적절한 값이 아닐 수 있습니다. 예를 들어 컴퓨터가 랩탑이고 애플리케이션이 일부 기록을 저장하거나 여러 파일에 로그인하고 드라이브가 종료 지점에서 절전 모드로 전환되는 경우 지연 시간을 약 15~30초로 늘립니다.