如何正确读取子进程 Popen 的输出? [英] How to read output from subprocess Popen correctly?

查看:33
本文介绍了如何正确读取子进程 Popen 的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 stderr 重定向到 stdout 并读取命令的输出.看起来代码有效,但是当它到达输出的末尾时,它会抛出异常

I'm trying to redirect stderr to stdout and read the output of a command. It looks like the code works, but when it reaches the end of the output, it throws an exception

代码:

with Popen(["bash", "-c", "for ((i=0;i<10;i++)); do echo $i; sleep .5; done"],
           stderr=subprocess.STDOUT) as proc:
    out, err = proc.communicate()
    for line in out:
        if line:
            print(line)

输出:

0
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-3c150d6a4092> in <module>()
      2            stderr=subprocess.STDOUT) as proc:
      3         out, err = proc.communicate()
----> 4         for line in out:
      5                 if line:
      6                         print(line)

TypeError: 'NoneType' object is not iterable

推荐答案

我明白了,你可以使用另一种方法实现你想要的,但我想解释一下你的第一个版本发生了什么.

I see, you can achive what you want using another approach, but I would like to explain what was happining with your first version.

问题是您在 proc 中没有任何用于输出的 PIPE,因此输出不会通过您的脚本移动",它直接进入屏幕,这就是您看到输出的原因:

The thing is you don't have any PIPE for output in proc, so the output don't "travel" through your script, it goes directly to the screen, thats the reason you see the output:

0
1
2
3
4
5
6
7
8
9

然后在一行中:

out, err = proc.communicate() # out is None, since you don't 
                              # pass the argument "stdout=subprocess.PIPE"
                              # when creating proc.

以及稍后当您尝试遍历 out 时:

and later when you try to iterate over out:

for line in out:  # TypeError: 'NoneType' object is not iterable
     ...          # We are talking about out variable here, which is None.
     print(line)  # This line never get hit.

解决方案.

这里有一个将 stdout 重定向到 stderr 并使用 communicate 的小例子:

Solution.

Here you have a little example redirecting stdout to stderr and using communicate:

import subprocess
import sys

proc = subprocess.Popen(['ls'], stderr=sys.stdout, shell=True) # Not the use of sys.stdout
out, err = proc.communicate()
print(err.decode("utf-8"))

这篇关于如何正确读取子进程 Popen 的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆