2014-08-28 177 views
0

我很抱歉如果这是一个重复问题,我尝试搜索网页,但大多数人使用sudo。执行subprocess.Popen时挂起('su',shell = True)

但是,我不能使用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() 

在上面提到的点上,程序至少停留30分钟以上。当我在Linux终端上运行“su”时,需要一两秒钟,有时候会少一点。

+0

它'_yybe_挂起为'su'尝试在控制台(_tty_)上与用户交互?另一方面,在我的Linux系统上,当_stdin_没有连接到_tty_:'echo echo | su' =>'su:必须从终端运行# – 2014-08-28 14:18:03

+1

您可能需要为此使用['pexpect'](http://pexpect.readthedocs.org/en/latest/)。 – dano 2014-08-28 14:19:16

+0

pexpect是否带有Python-2.7.5?如果没有,那么我就不能使用它。 – Everlight 2014-08-28 14:21:35

回答

0

这样就够了吗?

import subprocess 
p_su = subprocess.Popen('su', shell=True).communicate() 

我不知道确切的原因,但有一个音符in the documentation告诉:

不要使用标准输出=管或标准错误= PIPE这个功能,可以僵局基于子进程输出量。当需要管道时,使用Popen和communications()方法。

该说明显然适用于许多子过程方法。

+0

不太好,请记住,我需要输入密码。我也尝试过,但我不确定如何验证输出行以确定是否输入密码或其他内容。 – Everlight 2014-08-28 14:28:07

+0

我无法捕捉到返回值,可能期望/ pexpect是最好的方法! – Emilien 2014-08-28 14:50:46

+0

我正试图让预期/效益现在工作,它给我一个更好的回应。 :) 我们拭目以待。 – Everlight 2014-08-28 14:52:06

1

在挂起的瞬间,su正在等待您输入密码。它没有挂,它耐心等待。

如果您正在从命令行(如python my_program.py)运行此程序,请尝试输入一行废话并按回车。我希望err_su都会有这样的内容:

Password: 
su: Authentication failure 
+0

那么,你会建议如何解决我的代码? – Everlight 2014-08-28 14:34:16

+0

这取决于你正在尝试做什么。调用'su'是向更大目标迈进的一步。什么是更大的目标? – 2014-08-28 14:36:07

0

总体而言,我下面的问题@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() 

我希望这可以帮助别人!