일부 응용 프로그램은 완전히 종료되지 않고 프로세스가 그대로 유지됩니다. 제가 찾은 한 가지 예는 Foxit Reader입니다. 물론, 버그를 보고하고 애플리케이션을 수정하는 것이 가장 이상적인 상황이지만 이것이 불가능할 때도 있습니다. 예를 들어 Foxit Reader의 경우 개발자는 완전한 재작성 작업을 진행 중이므로 더 이상 현재 버전을 수정하지 않을 것이라고 말했습니다.
나는 응용 프로그램을 종료할 때 남은 프로세스가 자동으로 닫히도록 하고 싶습니다(물론 남은 프로세스를 더 만들지 않고). 어떻게 해야 하나요?
답변1
가장 쉬운 방법은 스크립트를 통해 프로그램을 시작하고 trap
전체 kill
프로세스 그룹을 설정하는 것입니다.
#!/bin/bash
trap "kill -9 -- -$$" ERR EXIT
/path/to/gui-programm
어떻게 작동하나요?
A는 trap
쉘 내장 명령입니다. 스크립트가 하나 이상의 신호를 받으면 특정 명령을 실행합니다. 이 경우 EXIT는 정상적인 종료(즉, GUI 프로그램 닫기)를 나타내고 ERR은 오류(예: CTRL+C또는 다른 이유로 Foxit이 종료됨)를 나타냅니다. 참조: man signal
및man bash
사용된 명령은 SIGKILL이 전송되는 kill
위치 입니다 -9
. kill
PID에 빼기 기호를 추가하여 단일 프로세스를 종료할 수 있습니다. 그러면 kill <pid>
전체 프로세스 그룹(즉, 프로세스와 모든 하위 프로세스 및 포크)에 영향을 줍니다. --
이는 다음 매개변수가 플래그로 해석되지 않도록 하기 위해 필요합니다. 즉, kill -9 -- -$pid
프로세스 그룹은 일정 기간 동안 종료됩니다.
$$
현재 쉘 스크립트의 PID입니다. GUI 프로그램은 스크립트의 자식 프로세스이고, GUI 프로그램 자체의 자식 프로세스도 스크립트에 소스로 연결된 프로세스 그룹의 일부입니다.
테스트하고 싶다면 여러 번의 수면을 사용하는 것이 좋습니다.
#!/bin/bash
#test script for kill via trap
trap "kill -9 -- -$$" ERR EXIT
for (( i=1 ; i<=100 ; i++ )) ; do
sleep 120
done
/path/to/gui-command
이제 GUI 명령을 종료하면 모든 절전 모드가 사라집니다. 트랩 섹션을 주석 처리하면 그대로 유지됩니다.
trap
자식 프로세스가 실패하더라도 실행을 보장하기 위해서는 상속이 필요합니다 set -E
.
#!/bin/bash
set -E
trap "kill -9 -- -$$" ERR EXIT
/path/to/gui-programm
답변2
한 가지 방법은 애플리케이션을 직접 시작하는 대신 스크립트에서 애플리케이션을 시작하는 것입니다. 애플리케이션이 실행되는 동안 해당 출력은 임시 파일로 파이프됩니다. 그런 다음 fifo에 대한 파이프를 통해 파일에 대해 tail을 실행합니다. 다음 grep은 fifo에 대해 실행됩니다. 일부 텍스트가 발견되면 tail 프로세스가 종료되고 fifo가 닫히고 애플리케이션 프로세스가 강제 종료되며 임시 파일이 삭제됩니다.
응용 프로그램이 종료될 때 마지막 텍스트 출력이 되도록 텍스트를 선택해야 합니다(명령줄에서 응용 프로그램을 시작하면 이 텍스트를 볼 수 있습니다). 예를 들어, FoxitReader를 닫으면 출력되는 마지막 텍스트는 "CJS_Module::ExitEnumJSPlugThread"입니다.
다음 예제 스크립트는 FoxitReader와 함께 작동하는 방법을 보여 주며 다른 응용 프로그램에 쉽게 적용할 수 있습니다.
#!/bin/bash
file=/tmp/foxit.txt
YOURPATH/foxitsoftware/foxitreader/FoxitReader "$@" &> $file &
foxitpid=$!
fifo=/tmp/tmpfifo.$$
mkfifo $fifo || exit 1
tail -f $file >$fifo &
tailpid=$!
grep -m 1 "CJS_Module::ExitEnumJSPlugThread" $fifo
kill $tailpid
rm $fifo
kill -9 $foxitpid
rm -f $file
exit 0
답변3
@mcarans의 답변에 따르면 Foxit Reader 설치 디렉터리에서 시작 스크립트를 미세 조정할 수 있습니다.
<INSTALLPATH>/foxitreader/FoxitReader.sh
이 스크립트를 다음과 같이 수정합니다(<INSTALLPATH> 확인을 잊지 마세요).
#!/bin/bash
selfpath="<INSTALLPATH>/foxitreader"
file=/tmp/foxit.txt
"$selfpath/FoxitReader" "$@" &> $file &
foxitpid=$!
fifo=/tmp/tmpfifo.$$
mkfifo $fifo || exit 1
tail -f $file >$fifo &
tailpid=$!
grep -m 1 "~CJS_Module()" -m 1 "CJS_Module::ExitEnumJSPlugThread()" $fifo
kill $tailpid
rm $fifo
kill -9 $foxitpid
rm -f $file
exit 0
저장하면 모든 준비가 완료됩니다. PDF 파일을 두 번 클릭하고 평소대로 닫으면 남은 프로세스가 없습니다.