在Python中使用sudo renice

3
一般而言,这是一个已经得到很好回答的问题。Linux不允许非特权用户降低PID的niceness值,而以root权限运行则会带来一些新的问题。
尽管如此,下面是我的具体解决方案:我有一个用户帐户来管理一些进程,该帐户拥有对renice等几个命令的无密码sudo权限。我还有一个脚本,是所有用户在该系统上的通用入口点。该脚本既可以运行常规用户程序,也可以运行由特殊帐户管理的进程。因此,当以特定选项运行脚本时,如果可以,应该进行renice操作,但如果不能,则保持静默。
我使用的代码如下:
subprocess.Popen(["sudo", "renice", "-20", str(process.pid)],
#                shell = True,
                 stdout = subprocess.DEVNULL,
                 stderr = subprocess.STDOUT)

如果shell = True被注释掉,该进程将获得新的niceness值。但如果我以非特权用户身份运行,则sudo会提示输入密码并破坏我的终端输出。按键变得不可见,一切看起来都很愚蠢。如果我取消注释shell = True,则不会在终端输出任何内容,但是即使作为root用户运行该进程也不会改变其niceness值。
损坏的终端输出可能是由于我使用的终端仿真器(尚未尝试其他仿真器)所致,但我希望合并这些行为。无论如何,sudo都没有响应,但如果用户可以成功使用sudo,则更改niceness值。
有任何建议吗?

1
我认为(但不完全确定)这是因为您没有TTY。可能是这个问题:https://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password - 尝试创建一个PTY(https://dev59.com/slgR5IYBdhLWcg3wO7bX#43012138),看看是否有帮助。 - drdaeman
1
没错!我正在使用3.x版本,所以在Popen中添加start_new_session=True会导致非特权用户无声地失败,而以root身份成功,因此我想它也适用于我的无密码sudo用户。太好了。如果您希望我接受答案,请随意发布。=) - pdm
1个回答

2
我认为这是因为即使不需要密码,sudo需要一个TTY。请尝试提供一个TTY:
import os
import pty
import subprocess

master, slave = pty.openpty()
p = subprocess.Popen(
    ["sudo", "id", "-a"],
    stdin=slave, stdout=slave, stderr=slave
)
os.close(slave)

output = os.read(master, 1026)
os.close(master)
print(output)

上面的代码应该打印出类似于 uid=0(root) gid=0(root) groups=0(root) 的内容。 如果是这样,那么请将 id 替换为 renice,删除不必要的 os.read 并尝试再次运行程序。
更新:在 OP 的情况下,它之所以失败是另一个原因。 在 Popen 中添加 start_new_session=True 后,对于非特权用户,它会无声地失败并作为 root 成功运行。

1
差不多了。我使用了 Popen 参数,但是你最初的评论让我找到了答案。非常感谢。=) - pdm

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