sudo 시 쉘 스크립트에서 "kill -- -$$"를 실행할 수 없습니다.

sudo 시 쉘 스크립트에서 "kill -- -$$"를 실행할 수 없습니다.

여러 백그라운드 하위 프로세스를 시작하는 쉘 스크립트가 있습니다. 상위 프로세스가 종료되거나 종료되지 않는 한 항상 실행되기를 원합니다. 따라서 하위 프로세스가 종료되면 항상 다시 시작되는 루프에 하위 프로세스가 있습니다.

이 스크립트를 직접 실행해 보면 비교적 잘 작동하는 것 같습니다. 하지만 이렇게 하면 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.

관련 정보