2010-01-25 67 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