通过sudo启动的子进程如何终止?

5
在我正在处理的项目中,有一些使用 sudo 启动长时间运行进程的代码:
subprocess.Popen(['sudo', '/usr/bin/somecommand', ...])

我希望在父进程退出时能够清理这个进程。目前,当父进程退出时,子进程仍然在运行(当然会重新附加到init)。

我不确定如何解决这个问题。该代码仅限于通过sudo运行某些命令,而授予运行 sudo kill 权限的普遍方式最多只是可疑的。

我没有一个可以关闭的子进程的开放管道(子进程不从stdin读取),我也无法修改子进程的代码。

在这种情况下,是否有其他机制可能会起作用?


好问题。我认为您无法终止不再由用户拥有的进程。从您的示例中,我假设您已经配置了 /etc/sudoers 以允许使用 sudo 运行程序而无需密码。您是否考虑过对 killall /usr/bin/somecommand 做同样的操作呢? - loopbackbee
2个回答

5
首先,我会回答这个问题。虽然我不认为这是一个好主意,但这就是你要求的。我会将那个子进程包装成一个可以监听标准输入的小程序。然后你可以使用sudo运行该程序,它将能够在没有sudo的情况下运行该进程,并且当你通过标准输入要求它这样做时,它将知道其pid并具有所需的权限以终止该进程。
然而,通常这种情况意味着使用无密码和安全性差的sudo。最常见的技术是降低程序的权限,而不是提高它们。在这种情况下,您应该创建一个由超级用户启动的运行程序,然后它使用降低权限启动您的主程序并侦听管道进行通信。当需要运行命令时,您的主程序告诉运行程序,运行程序执行任务。当需要终止命令时,您再次通过管道告诉运行程序。
常规规则如下:
1.如果需要超级用户权限,则应授予父进程。
2.如果子进程需要执行特权操作,则请求顶层进程代表其执行。
3.应尽可能使顶层进程保持尽可能小,并尽可能少地执行任务。它越大,就会在安全性方面产生更多漏洞。
这就是许多应用程序所做的。我想到的第一个例子是Apache Web服务器(至少在*nix上),它有一个小的顶层程序和预分叉的工作程序,它们不是以root/wheel/其他超级用户用户名运行的。

0

这将在最后一行引发OSError: [Errno 1] 操作不允许

p = subprocess.Popen(['sudo', '/usr/bin/somecommand', ...])
print p.stdout.read()
p.terminate()

假设sudo不会要求输入密码,一个解决方法是创建一个调用sudo的shell脚本...
#!/bin/sh
sudo /usr/bin/somecommand

然后在Python中执行以下操作:

p = subprocess.Popen("/path/to/script.sh", cwd="/path/to")
print p.stdout.read()
p.terminate()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接