Jon*_*Jon 8 linux bash sudo signals kill
我试图找出为什么这不起作用:
\n\n#!/bin/bash\n\nsudo sleep 60 &\nsudo_pid=$!\nsudo kill $sudo_pid\nRun Code Online (Sandbox Code Playgroud)\n\n我希望在之后kill,sudo命令及其子sleep进程将被终止,但它们没有,如以下脚本所示:
#!/bin/bash\n\nsudo sleep 60 &\nsudo_pid=$!\nsudo kill $sudo_pid\n\nif ps -p $sudo_pid > /dev/null; then\n sudo kill $sudo_pid\nelse\n echo "No sudo process running"\n exit 1\nfi\n\nif ps -p $sudo_pid > /dev/null; then\n echo "sudo (pid $sudo_pid) is still running"\n ps -F $sudo_pid\nelse\n echo "sudo successfully killed"\nfi\nRun Code Online (Sandbox Code Playgroud)\n\n当我运行它时会产生以下输出(带有sudo缓存的信用):
jon@ubuntu:~$ ./so.sh \nsudo (pid 46199) is still running\nUID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD\nroot 46199 46198 0 14764 3984 3 13:37 pts/0 S+ 0:00 sudo sleep 60\nRun Code Online (Sandbox Code Playgroud)\n\n脚本完成后(并且sudo sleep 60仍在运行),可以使用相同的命令杀死它:
jon@ubuntu:~$ ps -F 46199\nUID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD\nroot 46199 1 0 14764 3984 3 13:37 pts/0 S 0:00 sudo sleep 60\n\njon@ubuntu:~$ sudo kill 46199\n\njon@ubuntu:~$ ps -F 46199\nUID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD\n\njon@ubuntu:~$\nRun Code Online (Sandbox Code Playgroud)\n\n我注意到so.sh脚本退出后,父进程ID已从sudo sleep 60脚本更改为进程init,我认为这很重要。也可以sudo sleep 60从不同的 shell 成功终止该进程,同时so.sh当脚本仍在运行
我还注意到,sudo kill -ABRT在脚本中使用(而不是kill\ 的默认值SIGTERM)确实成功终止了该进程,所以我认为这与处理sudo方式有关。然而,根据手册页,我认为它不应该做任何特别的事情:sudoSIGTERM
Signal handling\n When the command is run as a child of the sudo process, sudo will relay\n signals it receives to the command. The SIGINT and SIGQUIT signals are\n only relayed when the command is being run in a new pty or when the sig\xe2\x80\x90\n nal was sent by a user process, not the kernel. This prevents the com\xe2\x80\x90\n mand from receiving SIGINT twice each time the user enters control-C.\nRun Code Online (Sandbox Code Playgroud)\n\n手册页中提到的唯一特殊处理SIGTERM是signals that were sent by the command it is running; 这里的情况并非如此。此外,我将ps -F上面的脚本更改为ps -o blocked,caught,ignored,pending它的输出
sudo (pid 46429) is still running\n BLOCKED CAUGHT IGNORED PENDING\n0000000000000000 00000001800b7a07 0000000000000000 0000000000000000\nRun Code Online (Sandbox Code Playgroud)\n\n这似乎表明 SIGTERM 没有被阻止或忽略,那么为什么进程没有sudo sleep 60被终止呢?
我已经想出了几种解决方法(setsid杀死sudo -b子sleep进程而不是父sudo进程),所以我不是在寻找替代方法的答案。我只是想了解这里发生了什么。
如果重要的话:
\n\njon@ubuntu:~$ uname -a\nLinux 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\njon@ubuntu:~$ sudo --version\nSudo version 1.8.20p2\nSudoers policy plugin version 1.8.20p2\nSudoers file grammar version 46\nSudoers I/O plugin version 1.8.20p2\nRun Code Online (Sandbox Code Playgroud)\n
小智 5
我在 sudo 的源代码中发现以下注释
/*
* 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.
*/
Run Code Online (Sandbox Code Playgroud)
如果你改变你sudo kill $sudo_pid的,setsid sudo kill $sudo_pid它就会起作用。
在这里找到这个:starting a new process group from bash script
任何给定信号的信号掩码位为:
(1ULL << ((signal_number) - 1))
Run Code Online (Sandbox Code Playgroud)
(无论如何,对于 1-32 范围内的标准信号;附加信号位于“实时”信号集中,并且处理方式略有不同,但应用相同的概念)。所以有趣的部分是CAUGHT是:
...7a07
Run Code Online (Sandbox Code Playgroud)
这是(+表示捕获,-表示未捕获,在扩展部分):
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
Run Code Online (Sandbox Code Playgroud)
(如果愿意,您可以继续解码其余部分;请参阅/usr/include/asm-generic/signal.hLinux 特定的信号编号;请注意,OSX 和 BSD 上的数字定义不同,但技术是相同的:捕获或阻止或任何信号在中表示为 1 位面具)。
所以,这个意思sudo是抓SIGTERM而不是抓SIGABRT。不传递肯定SIGTERM和代码本身有关系sudo。源代码 ( apt-get source sudo) 有一些相当复杂的代码用于执行信号处理,包括一些有趣的调试技巧,您可以在 sudo 配置文件中打开这些技巧来帮助您跟踪正在发生的情况。
| 归档时间: |
|
| 查看次数: |
1788 次 |
| 最近记录: |