python 中的 sudo renice

sudo renice in python

总的来说,这是一个很好回答的问题。 Linux 不允许非特权用户降低 PID 的友好度,并且 运行 以 root 用户身份运行是它自己的蠕虫罐头。

也就是说,这是我的具体情况:我有一个用户帐户可以管理一些进程,这些进程具有 renice 的无密码 sudo 权限和它使用的一些其他命令。我还有一个脚本,它是该系统上所有用户的公共入口点。此脚本既可以 运行 普通用户程序也可以由特殊帐户管理的进程。因此,当 运行 具有特定选项时,脚本应该 renice 如果可以,但如果不能则静默失败。

我得到的代码如下所示:

subprocess.Popen(["sudo", "renice", "-20", str(process.pid)],
#                shell = True,
                 stdout = subprocess.DEVNULL,
                 stderr = subprocess.STDOUT)

如果我将 shell = True 注释掉,该过程将获得新的好处,但如果我 运行 宁作为非特权用户,sudo 将退出其密码提示并破坏了我的终端输出。击键变得不可见,一切都变得愚蠢。如果我取消注释 shell = True,我不会得到终端输出。但是,即使我 运行 以 root 身份运行该进程,它的优点也没有改变。

损坏的终端输出很可能是因为我正在使用的终端仿真器(还没有用另一个仿真器尝试过)但我想合并这些行为。无论如何,来自 sudo 的沉默,但是如果用户可以成功地执行 sudo,那就是一个很好的改变。

有什么指点吗?

我认为这是因为 sudo requires a 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 的案例中,它因其他原因而失败。将 start_new_session=True 添加到 Popen 让非特权用户静默失败并以 root 身份成功。