$!를 사용하여 쉘 스크립트의 PID를 얻으면 올바른(최종) PID가 제공되지 않습니다.

$!를 사용하여 쉘 스크립트의 PID를 얻으면 올바른(최종) PID가 제공되지 않습니다.

나중에 종료할 수 있도록 쉘 스크립트의 PID를 얻으려고 합니다.

bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
echo "$!"

위의 내용은 실행되어 37977을 반환합니다.

하지만

내가 달릴 때 kill 37977나는 얻는다.

bash: kill: (37977) - No such process

내 생각엔 스크립트가 /home/lewis/builds/arduino/arduino-1.8.12/arduino37977 외에 다른 프로세스를 생성하기 때문인 것 같습니다.

쉘 스크립트나 내가 실행하는 다른 명령의 최종 PID를 얻을 수 있는 방법이 있습니까? 일반적으로 잘 작동하지만 이 인스턴스로 인해 문제가 발생합니다.

이런 일이 다시 발생할 경우를 대비해 다른 명령으로 이동할 수 있는 솔루션이 필요합니다.

답변1

생성된 프로세스가 다른 프로세스를 시작한 다음 종료하는 경우 새 프로세스는 모두 동일한 프로세스 그룹 ID(PGID)를 가져야 하며 해당 ID는 원래 프로세스의 PID(예에서는 37977)여야 합니다. 그래서 당신이 원하는 것은 PGID의 모든 프로세스를 종료하는 방법입니다. 이는 kill아래 설명된 대로 음수 PID를 사용하여 수행할 수 있습니다 man kill.

          -n     where n is larger than 1.  All processes in process group
                 n are signaled.  When an argument of  the  form  '-n'  is
                 given,  and it is meant to denote a process group, either
                 a signal must be specified first, or the argument must be
                 preceded  by a '--' option, otherwise it will be taken as
                 the signal to send.

그래서 당신이 원하는 것은 다음과 같습니다.

bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
kill -TERM -"$!"

개별 PID 목록을 수집해야 하는 경우 다음을 수행할 수 있습니다.

bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
ps -eo pgid,pid | awk -v pid=$! '$1==pid{print $2}')

그러면 PGID가 포함된 PID 목록이 반환됩니다 $!. 쉘이 배열을 지원하는 경우(bash는 지원) 다음을 수행할 수도 있습니다.

pids=($(ps -eo pgid,pid | awk -v pid=$! '$1==pid{print $2}'))
for pid in "${pids[@]}"; do echo "Killing $pid"; kill $pid; done

또는 필요한 다른 것.

관련 정보