2017-12-29 7 views
1

에서 보낸 SIGTERM 무시 :sudo는 내가이 작동하지 않는 이유를 알아 내려고 노력하고있어 동일한 스크립트

#!/bin/bash 

sudo sleep 60 & 
sudo_pid=$! 
sudo kill $sudo_pid 

내가 기대를 killsudo 명령 및 하위 sleep 과정이 될 것입니다 후 그 종료하지만,이 스크립트에 의해 같이 그들은하지 않습니다 :

: 나는 (캐시 sudo creds와 함께)를 실행할 때이 출력을 얻을 수

#!/bin/bash 

sudo sleep 60 & 
sudo_pid=$! 
sudo kill $sudo_pid 

if ps -p $sudo_pid > /dev/null; then 
    sudo kill $sudo_pid 
else 
    echo "No sudo process running" 
    exit 1 
fi 

if ps -p $sudo_pid > /dev/null; then 
    echo "sudo (pid $sudo_pid) is still running" 
    ps -F $sudo_pid 
else 
    echo "sudo successfully killed" 
fi 

스크립트가 완료되면, 가 동일한 명령으로 죽일 가능하다 (그리고 sudo sleep 60은 여전히 ​​실행) :

[email protected]:~$ ps -F 46199 
UID   PID PPID C SZ RSS PSR STIME TTY  STAT TIME CMD 
root  46199  1 0 14764 3984 3 13:37 pts/0 S  0:00 sudo sleep 60 

[email protected]:~$ sudo kill 46199 

[email protected]:~$ ps -F 46199 
UID   PID PPID C SZ RSS PSR STIME TTY  STAT TIME CMD 

[email protected]:~$ 

내가 알 그 so.sh 스크립트 종료 후, 부모 프로세스 ID에 대한 sudo sleep 60이 스크립트에서 init 프로세스로 변경되었습니다. 이는 상당히 중요하다고 생각합니다. so.sh 스크립트가 아직 실행 중일 때 sudo sleep 60 프로세스를 다른 셸에서 성공적으로 종료 할 수도 있습니다.

는 또한 성공적으로 sudo 프로세스를 종료 않습니다 ( kill의 기본 SIGTERM 반대), 그래서 그 가정 스크립트에서 sudo kill -ABRT를 사용하여 sudoSIGTERM 처리하는 방식과 함께 할 수있는 뭔가가 나타났습니다. 그러나, 사람의 페이지를 기반으로, 나는 그것이 특별한 아무것도해야한다고 생각하지 않습니다

Signal handling 
    When the command is run as a child of the sudo process, sudo will relay 
    signals it receives to the command. The SIGINT and SIGQUIT signals are 
    only relayed when the command is being run in a new pty or when the sig‐ 
    nal was sent by a user process, not the kernel. This prevents the com‐ 
    mand from receiving SIGINT twice each time the user enters control-C. 

맨 페이지에서 언급 SIGTERM의 유일한 특수 처리가 signals that were sent by the command it is running입니다; 여기서는 그렇지 않습니다. 또한, 나는 ps -o blocked,caught,ignored,pending에 위의 스크립트에서 ps -F을 변경하고 출력

그 SIGTERM이 차단되거나 무시되지 않는 것처럼 보입니다, 왜 종료 점점 sudo sleep 60 과정이 아닌
sudo (pid 46429) is still running 
     BLOCKED   CAUGHT   IGNORED   PENDING 
0000000000000000 00000001800b7a07 0000000000000000 0000000000000000 

?

나는 (부모 sudo 과정보다는 아이 sleep 과정을 죽이는 setsid, sudo -b) 몇 가지 해결 방법을 마련했습니다, 그래서 다른 방법의 답을 찾는 게 아니에요. 나는 여기서 무슨 일이 벌어지고 있는지 이해하고 싶다.

이 경우는 문제 :

[email protected]:~$ uname -a 
Linux ubuntu 4.13.0-16-generiC#19-Ubuntu SMP Wed Oct 11 18:35:14 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 
[email protected]:~$ sudo --version 
Sudo version 1.8.20p2 
Sudoers policy plugin version 1.8.20p2 
Sudoers file grammar version 46 
Sudoers I/O plugin version 1.8.20p2 

답변

1

주어진 신호에 대한 신호 마스크 비트는 다음

(1ULL << ((signal_number) - 1)) 

(어쨌든 1-32 범위의 기준 신호

추가의 신호가에 "실시간"신호 세트이며 동일한 개념이 적용되지만 다소 다르게 처리됩니다.그래서 CAUGHT 마스크의 흥미로운 부분은 다음과 같습니다이다

...7a07 

(적발을위한 +, - 확장 된 부분에서 잡은하지 않는) :

xxx7: signals 1, 2, 3, but not 4: +SIGHUP +SIGINT +SIGQUIT -SIGILL 
xx0x: not 5-8:     -SIGTRAP -SIGABRT -SIGBUS -SIGFPE 
xaxx: not 9, 10, not 11, 12:  -SIGKILL +SIGUSR1 -SIGSEGV +SIGUSR2 
7xxx: 13, 14, 15, not 16:   +SIGPIPE +SIGALRM +SIGTERM -SIGSTKFLT 

는 (당신은 나머지 경우 디코딩을 계속할 수 있습니다 당신은 좋아한다 : 리눅스 고유의 신호 번호는 /usr/include/asm-generic/signal.h을 참조하라. 숫자 정의는 OSX와 BSD에서 다르지만 기술은 동일하다 : 잡히거나 막혔거나 어떤 신호가 마스크에서 1 비트로 표현되는지).

따라서 sudoSIGTERM을 포착했지만 SIGABRT은 포착하지 못했습니다. SIGTERM이 전달되지 않으면 코드 sudo과 관련이 있어야합니다. 소스 (apt-get source sudo)는 신호 처리를하기위한 다소 복잡한 코드를 가지고 있습니다. 흥미있는 디버그 트릭을 포함하여 sudo 설정 파일에서 켜서 무슨 일이 일어나는지 추적 할 수 있습니다.

+0

신호에 대한 추가 정보를 보내 주셔서 감사합니다! 'sudo'가 자식 프로세스에서 시작될 때 그 신호를 전파하지 않기 때문에'sudo'가'SIGTERM'을 잡는 것이 당연합니다. 내가 정말로 알고 싶다면 소스를 파헤쳐 야 할 것 같다. – Jon

관련 문제