当前位置: 首页 > 面试题库 >

您可以像往常一样使python子进程输出stdout和stderr,但也可以将输出捕获为字符串吗?

姜聪
2023-03-14
问题内容

在这个问题中,hanan-n询问是否有可能有一个向stdout输出的python子进程,同时还将输出保留在字符串中以供以后处理。在这种情况下,解决方案是遍历每条输出线并手动打印它们:

output = []
p = subprocess.Popen(["the", "command"], stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print(line)
    output.append(line)

但是,此解决方案不能推广到您想要对stdout和stderr都执行此操作的情况,同时满足以下条件:

  • 来自stdout / stderr的输出应分别转到父进程的stdout / stderr
  • 输出应尽可能实时完成(但我只需要最后访问字符串)
  • stdout和stderr行之间的顺序不应更改(我不确定如果子进程以不同的时间间隔刷新其stdout和stderr缓存,该方法甚至如何工作;让我们现在假设我们将所有内容都放入包含完整内容的漂亮块中线?)

我浏览了子流程文档,但找不到任何可以实现此目的的东西。我能找到的最接近的方法是添加stderr=subprocess.stdout并使用与上述相同的解决方案,但随后我们就失去了常规输出和错误之间的区别。有任何想法吗?我猜测解决方案-
如果有的话-将涉及对p.stdout和的异步读取p.stderr

这是我想做的一个例子:

p = subprocess.Popen(["the", "command"])
p.wait()  # while p runs, the command's stdout and stderr should behave as usual
p_stdout = p.stdout.read()  # unfortunately, this will return '' unless you use subprocess.PIPE
p_stderr = p.stderr.read()  # ditto
[do something with p_stdout and p_stderr]

问题答案:

这个例子似乎对我有用:

# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4

import subprocess
import sys
import select

p = subprocess.Popen(["find", "/proc"],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

stdout = []
stderr = []

while True:
    reads = [p.stdout.fileno(), p.stderr.fileno()]
    ret = select.select(reads, [], [])

    for fd in ret[0]:
        if fd == p.stdout.fileno():
            read = p.stdout.readline()
            sys.stdout.write('stdout: ' + read)
            stdout.append(read)
        if fd == p.stderr.fileno():
            read = p.stderr.readline()
            sys.stderr.write('stderr: ' + read)
            stderr.append(read)

    if p.poll() != None:
        break

print 'program ended'

print 'stdout:', "".join(stdout)
print 'stderr:', "".join(stderr)

通常,在任何情况下您想同时处理多个文件描述符,却又不知道哪个文件可以读取内容,则应使用select或等效方法(例如Twisted Reactor)。



 类似资料:
  • 问题内容: 我了解到,在Python中执行命令时,应该使用子进程。我想要实现的是通过ffmpeg对文件进行编码,并观察程序输出,直到文件完成。Ffmpeg将进度记录到stderr。 如果我尝试这样的事情: 调用child.communicate()后,程序无法继续执行,并等待命令完成。还有其他方法可以跟踪输出吗? 问题答案: communication()阻塞直到子进程返回,所以循环中的其余各行仅

  • 问题内容: 我有一个Java应用程序,即Voip。我正在使用一个套接字通过线程同时发送和接收信息。代码如下所示。 我发现的问题是,当我写入输出流时,它在第一次写入时阻塞。我发送的字节数不多。贝娄是我的写代码。 读取声音代码的另一个线程是… 我已经在实际代码中注释了很大一部分,因为我只是想使其正常工作。我的写函数在第一次写时无限期阻塞。这可能是我的线程有问题吗?我唯一的想法是输出和输入流共享我的套接

  • 命名为 101.py 运行 nameko run 101 需要安装 nameko 可以通过 pip install nameko 输出如下: 很奇怪,明明 handlers 是空列表,但是 「哈哈哈哈」 还是输出到了标准输出中 为什么?我只知道需要输出到标准输出,必须通过配置 handlers 难道还有不用配置 handlers 就可以输出到标准输出的方式? 不通过 nameko run 101

  • 根据这个问题的答案:停止Excel自动将某些文本值转换为日期我正在尝试使用python的CSV模块创建一个CSV文件,某些字段的格式为 但是,我无法让CSV编写器生成这样的输出。如果我使用默认的 csvwriter(没有特殊参数)并预先格式化我的数据,它会尝试引用我的所有引号,并且我得到的输出如下所示: 如果我将csv编写器的引用级别设置为QUOTE_NONE,那么我得到一个“错误:需要转义,但没

  • 问题内容: 我想写一个像这样的doctest: 有什么办法吗?我认为切换到单元测试会更有意义,但我很好奇是否可以指定不适合doctest中的测试的输出范围。 谢谢! 问题答案: 使用,您可以用来表示“在此处匹配任何字符串”。您可以使用doctest指令设置选项,以使其仅在一个测试用例中处于活动状态:在线文档中的一个示例是: 如果您希望doctest选项始终处于活动状态,则可以将其作为参数传递给您使

  • 我有以下问题。我(完全菜鸟)想在不使用日历库的情况下获得一年中的一天来完成我的大学任务。 所以我在这里写我的代码,就像我认为它应该是这样的,但不知怎么的,我的结果得到了不同的结果,就像他们应该做的那样,我真的不知道为什么。我的代码很简单,我想也许你们中的一个人可以看到我的问题。现在已经过去了1-2个小时,时间对我来说已经不多了。 在我的程序的主要方法中,你可以清楚地看到我记录的内容,我希望有人能看