Python 执行subprocess.Popen时挂起(';su';,shell=True)

Python 执行subprocess.Popen时挂起(';su';,shell=True),python,linux,python-2.7,Python,Linux,Python 2.7,我很抱歉,如果这是一个重复的问题,我试图搜索网络,但大多数人使用sudo 但是,我不能使用sudo,我可以使用'su'作为root用户登录。我正在执行以下代码: try: p_su = subprocess.Popen('su', stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True) out_su, err_su = p_su.communicate() # >>> The program

我很抱歉,如果这是一个重复的问题,我试图搜索网络,但大多数人使用sudo

但是,我不能使用sudo,我可以使用'su'作为root用户登录。我正在执行以下代码:

try:
    p_su = subprocess.Popen('su', stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
    out_su, err_su = p_su.communicate()
    # >>> The program hangs here. <<<
except:
    print "Unable to login as root (su). Consult the Software Engineer."
    sys.exit()

print out_su
if "Password" in out_su:
    try:
        p_pw = subprocess.Popen('password', stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
        out_pw, err_pw = p_pw.communicate()
    except:
        print "Unable to login as root (password). Consult the Software Engineer."
        sys.exit()
试试看:
p_su=subprocess.Popen('su',stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
out_su,err_su=p_su.communicate()
#>>>程序挂在这里 这是否足够

import subprocess
p_su = subprocess.Popen('su', shell=True).communicate()
我不知道确切的原因,但有一张便条告诉我:

不要将stdout=PIPE或stderr=PIPE与此函数一起使用,因为这可能会基于子进程输出卷死锁。需要管道时,请将Popen与communicate()方法一起使用


注释显然适用于许多子流程方法。

在挂起时,
su
正在等待您键入密码。它不是挂着的,它在耐心地等待

如果您是从命令行(如
python my_program.py
)运行此程序,请尝试键入一行废话并单击return。我希望
err_su
的内容如下:

Password: 
su: Authentication failure

总的来说,@Thimble在我的问题下面的评论是正确的

因此,由于
subprocess.Popen
将不提供我想要的输出,因此我需要执行以下操作:

try:
    child = pexpect.spawn("su")
expect:
    print "Unable to login as root. Consult the Software Engineer."
    sys.exit()

i = child.expect([pexpect.TIMEOUT, "Password:"])

if i == 0
    print "Timed out when logging into root. Consult the Software Engineer."
    sys.exit()
if i == 1
    child.sendline("password")
    print "Logged in as root"
    sys.exit()

我希望这对其他人有帮助

它可能挂起为
su
尝试在控制台上与用户交互(tty)?另一方面,在我的Linux系统上,
su
在stdin未连接到tty时中止:
echo-echo | su
=>
su:必须从终端运行,您可能需要使用它。pexpect是否随Python-2.7.5一起提供?如果没有,那我就不能用了。西尔文,我不太清楚你在说什么,当你说“控制台(tty)”的时候,你指的是什么?(对不起,我不熟悉Linux和Python)本质上
su
是一个交互式提示,与登录完全相同。正因为如此,该命令从来没有实际的返回代码,因此它从来没有真正“完成”该命令。这就是它挂起的原因,也是您不能等到它完成后再发送密码的原因。解决这一问题的唯一方法是使用expect模块,如
pexpect
,或者使用提升的
su
权限运行python程序,这样运行后面的任何命令都不需要密码。不完全是,记住,我需要输入密码。我也试过了,但我不确定如何验证输出行以确定是否输入密码或其他内容。我也无法捕获返回值,也许expect/pexpect最终是一种更好的方法!我现在正努力让expect/pexpect工作,它给了我更好的回应我们拭目以待。这取决于你想做什么。调用
su
是迈向更大目标的一步。更大的目标是什么?