2010-01-25 82 views
15

我使用子進程模塊調用外部程序(plink.exe)登錄到服務器;但是當我調用通信來讀取輸出時,它是阻塞的。代碼如下:蟒蛇子進程通信()塊

import subprocess 
process = subprocess.Popen('plink.exe [email protected] -pw 123456'.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
print process.communicate() #block here 

我知道這個塊是因爲plink.exe它還在運行;但我需要在子進程終止之前讀取輸出。無論如何要這樣做?

+0

你需要與砰砰互動,或者你只需​​要撥打電話和閱讀標準輸出沒有阻塞? – Khelben 2010-01-25 15:42:20

+0

相關:[Python:從subprocess.communicate()讀取流式輸入)(http://stackoverflow.com/q/2715847/4279) – jfs 2015-05-09 14:14:44

回答

26

communicate方法的全部用途是等待該過程完成並返回所有輸出。如果您不想等待,請不要撥打communicate。而是從stdoutstderr屬性中讀取以讀取輸出。

如果過程輸出到stdoutstderr(並且您想要單獨閱讀),則必須小心地從兩者都讀取而不發生阻塞,否則可能會死鎖。這在Windows上相當困難,您可能希望使用pexpect模塊。

+0

'pexpect'在Windows上不起作用。可以使用['asyncio'](http://stackoverflow.com/a/20697159/4279)或[threads](http://stackoverflow.com/a/4896288/4279)讀取兩個流而不阻塞。 – jfs 2015-05-09 14:13:26

0

我面臨類似的情況,我必須執行一個命令lmstat -a,然後得到終端的輸出。

如果你只需要運行一個命令,然後讀取輸出,你可以使用下面的代碼:

import subprocess 

Username = 'your_username' 
Password = 'your_password' 
IP = 'IP_of_system' 
Connection_type = '-ssh' #can have values -ssh -telnet -rlogin -raw -serial 

p = subprocess.Popen(['plink', Connection_type, '-l', Username, '-pw', Password, IP], \ 
        shell = False, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
out, err = p.communicate('lmstat -a\nexit\n'.encode()) 
print(out.decode()) 
+1

正如@Thomas所說,這是一種阻塞而非非阻塞的方法 – Fookatchu 2014-06-02 12:49:09