스크립트에서는 kill이 작동하지 않지만 터미널에서는 작동하는 이유는 무엇입니까?

스크립트에서는 kill이 작동하지 않지만 터미널에서는 작동하는 이유는 무엇입니까?

내 문제를 설명하기 위해 설계된 다음 스크립트가 있습니다.

#!/bin/bash
set -eux
sudo sleep 120 &
spid=$!
sleep 1
sudo kill $spid
wait $!

이것은 인쇄됩니다

$ ./test.sh 
+ spid=21931
+ sleep 1
+ sudo sleep 120
+ sudo kill 21931
+ wait 21931

그런 다음 시간이 다 될 wait때까지 계속하세요 . sleep 120그러나 sudo kill 21931다른 터미널에서 실행하면 잠자는 프로세스가 즉시 종료됩니다. sudo kill $spid스크립트의 줄에서도 절전 프로세스가 즉시 종료될 것으로 예상했습니다 . 이것이 작동하지 않는 이유는 무엇이며 작동하게 만드는 방법은 무엇입니까?

(아마도 관련이 있을 수 있습니다. Ubuntu 15.10의 bash 4.3.42 및 dash 0.5.7에서 이 동작을 보았습니다.)

답변1

이유는 다음과 같습니다.소스 코드스도:

/*
 * Do not forward signals sent by a process in the command's process
 * group, as we don't want the command to indirectly kill itself.
 * For example, this can happen with some versions of reboot that
 * call kill(-1, SIGTERM) to kill all other processes.
 */

답변2

차이점은 /etc/sudoers 파일에 있을 수 있습니다. 어쩌면 사용자가 한 컴퓨터에서는 nopasswd를 사용하여 kill을 실행할 수 있지만 다른 컴퓨터에서는 실행할 수 없을 수도 있습니다.

답변3

이 이상한 동작이 Ubuntu 17.10 bash 4.4.12(1)-릴리스(x86_64-pc-linux-gnu)에서도 발생한다는 것을 확인했습니다.

정확한 원인은 알 수 없으나, 프로세스 신호와 관련된 것으로 보입니다. 기본적으로 소프트 종료 신호가 kill방출됩니다 . 15 – TERM그러나 hard 를 사용하면 9 – KILL잠자는 프로세스가 즉시 종료됩니다.

#!/bin/bash
set -eux
sudo sleep 120 &
spid=$!
sleep 1
sudo kill -9 $spid
wait $!

인쇄해 보세요

$ ./test.sh 
+ spid=4342
+ sleep 1
+ sudo sleep 120
+ sudo kill -9 4342
./test.sh: line 6:  4342 Killed                  sudo sleep 120
+ wait 4342

답변4

비슷한 문제가 발생하여 여기에 도착했습니다. 다른 답변은 도움이 되지 않습니다. 내 스크립트는 다음과 같이 ID를 Kill로 파이프합니다.

echo $some_output | awk '{print $1}' | xargs kill -9

이는 터미널에서는 작동하지만 스크립트에서는 작동하지 않습니다. 이 답변을 찾은 후 말하세요.Kill은 stdin에서 PID를 읽지 않습니다., 스크립트를 이것으로 변경하고 문제를 해결했습니다.

pids=`echo $some_output | awk '{print $1}'`

for p in $pids; do
    echo "Killing $p"
    kill -9 $p
done

저처럼 여기 오시는 분들에게 도움이 되길 바랍니다!

관련 정보