여러 백그라운드 하위 프로세스를 시작하는 쉘 스크립트가 있습니다. 상위 프로세스가 종료되거나 종료되지 않는 한 항상 실행되기를 원합니다. 따라서 하위 프로세스가 종료되면 항상 다시 시작되는 루프에 하위 프로세스가 있습니다.
이 스크립트를 직접 실행해 보면 비교적 잘 작동하는 것 같습니다. 하지만 이렇게 하면 sudo
다른 프로세스가 제대로 정리되지 않습니다.
#!/bin/bash
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
# Start first background thing
while true;
do
sleep 1
echo "SOME PROCESS RUNNING IN THE BACKGROUND"
echo "SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES"
sleep 5
done &
# Start second background thing
while true;
do
sleep 3
echo "ANOTHER ONE..."
sleep 3
done &
# Wait for quit keypress
while true
do
echo "Press 'Q' to quit"
read -rsn1
if [ $REPLY == "q" ] || [ $REPLY == "Q" ]; then
echo "Are you sure? [Y/N]"
read -rsn1
if [ $REPLY == "y" ] || [ $REPLY == "Y" ]; then
kill -- -$$
exit
fi
fi
echo ""
sleep 1
done
# Wait
wait
sudo할 때 CTRL+C를 누르거나 "Q"를 눌러 종료하면 상위(기본) 프로세스는 종료되지만 하위 프로세스는 종료되지 않으며 다음 오류가 발생합니다.
adam@TG-BBCAM-01:~ $ sudo ./temp.sh
Press 'Q' to quit
Are you sure? [Y/N]
./temp.sh: line 31: kill: (-29098) - No such process
./temp.sh: line 1: kill: (-29098) - No such process
adam@TG-BBCAM-01:~ $ SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND
명백히, 그것이 아이들을 죽이지 않았기 때문에 그들은 여전히 실행 중이고 내 쉘에서 출력을 계속하고 있습니다. sudo를 사용하지 않을 때 잘 작동합니다.
kill -- -$$
그것은 내 스크립트의 함정이자 "키 모니터" 부분 인 것 같습니다 . 하나를 주석 처리해도 다른 하나의 문제가 해결되지는 않습니다.
이 문제를 어떻게 해결할 수 있는지 아는 사람 있나요? 나는 그것이 대부분의 경우에 작동하기를 바랍니다(적어도 sudo가 필요한지 여부는).
감사해요!
답변1
응 kill -- -"$pgid"
, 그건 하나의 과정이어야 해그룹ID. 이는 쉘이 프로세스 그룹 리더인 경우에만 작동하지만 kill -- -"$$"
대화형 쉘에서 실행될 때는 작동하지 않습니다.sudo
$ sudo bash -c 'ps -j; exit'
PID PGID SID TTY TIME CMD
26786 26786 29719 pts/39 00:00:00 sudo
26794 26786 29719 pts/39 00:00:00 bash
26795 26786 29719 pts/39 00:00:00 ps
sudo
가 아닌 프로세스 그룹 리더가 되십시오 bash
.
따라서 다음을 수행 kill -- -"$(ps -o pgid= -p "$$")"
하거나 간단히 수행해야 합니다.
kill 0
이것은 자신의 프로세스 그룹을 종료하는 명령입니다.
그럼에도 불구하고 이는 스크립트가 대화형 셸에서 개별적으로 호출되는 경우(작업 제어 실행)에만 유효합니다.
다음 사항도 참고하세요.
(the-script; echo "$?")
또는:
the-script | cmd
첫 번째나 cmd
두 번째 경우의 하위 쉘도 동일한 프로세스 그룹에 배치되므로 마찬가지로 종료됩니다 kill 0
.