我正在考虑一个场景,我想运行一个程序/命令作为sudo
软件测试的一部分。这些命令是从基于模块的 Python 脚本启动的subprocess
。我试图避免必须使用超级用户权限运行整个测试套件。
就本示例而言,我们假设top
。我的命令启动了它自己的一些子进程,并且可能会遇到死锁。超时后,我想杀死它(及其子项)。显而易见的解决方案似乎是让我的命令成为一个新会话/进程组的负责人,允许我立即杀死它及其子进程。我不知道如何使其与sudo
.就我而言,sudo
始终受到密码保护,无一例外,我希望保持这种方式......如果可能的话。
- 作品:
setsid top
- 有效,但不会生成新的进程组:
sudo setsid top
- 有问题 - 很难以安全可靠的方式获取 root 密码:
setsid sudo top
我没能让(3)以一种干净的方式工作。我乱搞了SUDO_ASKPASS
。
令我惊讶的是,(2) 实际上运行了,但没有给我所需的新进程组。
systemd─┬─ ...
├─kdeinit5─┬─ ...
│ └─yakuake─┬─2*[bash]
│ ├─bash───sudo───top
│ ├─bash───pstree
...
答案1
场景 2 可以这样修复,无需使用setsid
:
sudo -b command
这将在系统的 init 进程的正下方创建一个新的进程组,包括该sudo
命令。
不过,有一点建议是:如果使用 Python 启动一个像这样的进程组subprocess.Popen
,则生成的对象PID
( subprocess.Popen(...).pid
) 不能用于确定PGID
最终使用的模式,例如kill -9 -- -{PGID}
(它将杀死 Python 解释器而不是新生成的进程)团体)。我的解决方法(需要psutil
):
import os
import psutil
import subprocess
def __get_pid__(cmd_line_list):
for pid in psutil.pids():
proc = psutil.Process(pid)
if cmd_line_list == proc.cmdline():
return proc.pid
return None
cmd = ['sudo', '-b', 'command']
cmd_proc = subprocess.Popen(cmd)
print('Wrong PGID: %d' % os.getpgid(cmd_proc.pid))
print('Right PGID: %d' % os.getpgid(__get_pid__(cmd)))