在Ubuntu 15.10中无法终止使用python创建的sudo进程

在Ubuntu 15.10中无法终止使用python创建的sudo进程,第1张

在Ubuntu 15.10中无法终止使用python创建的sudo进程

TL; DR

sudo
命令的处理组中由过程向前发送信号自2014
5月28日提交
的释放
sudo1.8.11
-蟒处理(须藤的父)和tcpdump的处理(孙子)是通过默认,因此相同的处理组中的
sudo
不将
SIGTERM
发送的信号转发
.terminate()
tcpdump
进程。


在以root用户和普通用户+ sudo身份运行该代码时,它显示出相同的行为

以正常用户身份运行会引发

OSError: [Errno 1] Operation not permitted
异常
.terminate()
(如预期)。

以as身份运行会

root
重现该问题:
sudo
tcpdump
不会终止进程,
.terminate()
并且代码仍停留
.communicate()
在Ubuntu
15.10上。

相同的代码会在Ubuntu 12.04上杀死这两个进程。

tcpdump_process
名称具有误导性,因为变量引用的是
sudo
进程(子进程),而不是
tcpdump
(孙子进程):

python└─ sudo tcpdump -w example.pcap -i eth0 -n icmp   └─ tcpdump -w example.pcap -i eth0 -n icmp

正如@ Mr.E在评论中指出的那样,您不需要

sudo
在这里:您已经是root用户了(尽管您不应该是root用户-
您可以在没有root用户的情况下嗅探网络)。如果你跌落
sudo
;
.terminate()
作品。

通常,

.terminate()
不会递归杀死整个进程树,因此可以预期孙进程可以生存。虽然
sudo
是一种特殊情况,但从sudo(8)手册页中可以得出:

当命令作为

sudo
进程的子级运行时,
sudo
会将 收到的 信号中继 到命令。重点是我的

即,

sudo
应该传达
SIGTERM
tcpdump
tcpdump
应该停止抓包
SIGTERM
,tcpdump的距离(8)手册页:

Tcpdump将继续捕获数据包,直到它被SIGINT信号(例如,通过键入您的中断字符,通常为control-
C生成)或SIGTERM信号(通常由kill(1)命令生成)中断为止;

即, 预期的行为是

tcpdump_process.terminate()
发送SIGTERM
sudo
,将
tcpdump
应停止捕获的信号中继到SIGTERM
,两个进程都退出,
.communicate()
并将
tcpdump
的stderr输出返回到python脚本。

注意:原则上,可以从同一sudo(8)手册页运行命令而无需创建子进程:

在特殊情况下,如果策略插件未定义关闭函数且不需要pty,

sudo
则将直接执行命令,而不是先调用fork(2)

因此

.terminate()
可能会
tcpdump
直接将SIGTERM发送给该进程-尽管不是解释原因:
sudotcpdump
在我的测试中,同时在Ubuntu 12.04和15.10上创建了两个进程。

如果我

sudo tcpdump -w example.pcap -i eth0 -n icmp
在外壳中运行,则将
kill-SIGTERM
终止两个进程。它看起来不像Python问题(Python 2.7.3(在Ubuntu 12.04上使用)在Ubuntu
15.10上的行为相同。Python3也在此处失败)。

它与流程组(作业控制)有关:传递

preexec_fn=os.setpgrp
subprocess.Popen()
这样,
sudo
它将进入一个新的流程组(作业),在该流程组中,它是领导者,如
tcpdump_process.terminate()
在这种情况下在shell中进行工作。

发生了什么?它适用于以前的版本。

解释在sudo的源代码中:

不要转发命令的进程组中某个进程发送的信号
,也不要转发该信号,因为我们不希望孩子间接杀死自己。例如,某些版本的重新引导会调用kill(-1,SIGTERM)杀死所有其他进程,这可能会发生。重点是我的

preexec_fn=os.setpgrp
更改
sudo
的流程组。
sudo
的子孙(例如
tcpdump
process)继承了该组。
python
并且
tcpdump
不再位于同一个进程组中,因此发送的信号
.terminate()
被中继
sudo
tcpdump
并退出。

Ubuntu 15.04使用问题

Sudo version 1.8.9p5
中的代码按原样工作。

Ubuntu 15.10使用

Sudo version1.8.12
包含提交的内容。

wily(15.10)中的sudo(8)手册页仍然只谈到子进程本身,而没有提及进程组:

作为一种特殊情况,sudo不会中继正在运行的命令发送的信号。

应该改为:

作为特殊情况,sudo不会中继正在运行的命令的进程组中的某个进程发送的信号。

您可以在Ubuntu的错误跟踪器和/或上游错误跟踪器上打开一个文档问题。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5648714.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存