3

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

也就是说,这是我的具体情况:我有一个用户帐户,它管理一些具有无密码sudo权限的进程renice以及它使用的一些其他命令。我还有一个脚本,它是该系统上所有用户的公共入口点。该脚本既可以运行常规用户程序,也可以运行特殊帐户管理的进程。因此,脚本在使用特定选项运行时,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 会改变。

任何指针?

4

1 回答 1

2

我认为这是因为sudo需要 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). 如果是这样,那么用 替换idrenice删除不必要的os.read,你应该很好。

更新:在 OP 的情况下,它因另一个原因而失败。添加start_new_session=TruePopen它对非特权用户静默失败并以root身份成功。

于 2017-06-15T19:49:39.443 回答