【问题标题】:python subprocess communicate() blockpython子进程通信()块
【发布时间】:2011-01-09 03:41:07
【问题描述】:

我正在使用子进程模块调用外部程序(plink.exe)来登录服务器;但是当我调用通信来读取输出时,它是阻塞的。代码如下:

 import subprocess
 process = subprocess.Popen('plink.exe hello@10.120.139.170 -pw 123456'.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 print process.communicate() #block here

我知道阻塞是因为plink.exe 它还在运行;但我需要在子进程终止之前读取输出。有什么办法吗?

【问题讨论】:

标签: python subprocess blocking


【解决方案1】:

communicate 方法的全部目的是等待进程完成并返回所有输出。如果您不想等待,请不要拨打communicate。而是从stdoutstderr 属性中读取以读取输出。

如果进程同时输出到stdoutstderr(并且您想单独阅读),则必须小心地从两者中实际读取而不会阻塞,否则您可能会死锁。这在 Windows 上相当困难,您可能希望改用 pexpect 模块。

【讨论】:

  • pexpect 在 Windows 上不起作用。 asynciothreads 可用于读取两个流而不会阻塞。
【解决方案2】:

我遇到过类似的情况,我必须执行单个命令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())

【讨论】:

  • 正如@Thomas 所说,这是一种阻塞而不是非阻塞的方法
【解决方案3】:

可能是因为“plink.exe”需要接受输入参数,如果你不传递它们,它将阻塞直到给出数据,你可以尝试在方法communicate(input)中添加参数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    相关资源
    最近更新 更多