2014-08-28 105 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() 

我希望這可以幫助別人!