【问题标题】:Merge stdout and stderr with Python popen AND detect if stderr is empty使用 Python popen 合并 stdout 和 stderr 并检测 stderr 是否为空
【发布时间】:2018-02-04 17:06:22
【问题描述】:

我想运行一个带有 popen 的子进程,它可以向 stdout 和 stderr 发送消息,但是尽管写入 stderr,该子进程仍将继续以愉快的方式继续。

我想将 stdout 和 stderr 一起流式传输,以便按照它发生的确切顺序获得输出(或者我猜从技术上讲是被刷新了)。然后,我想记录完整的结果集。但我也想独立知道 stderr 是否为空。如果不是,我将抛出一个异常。

我很清楚如何将它们分开或合并在一起,但我如何才能同时做到这两者?

【问题讨论】:

  • 如何将它们合并在一起?您是指在屏幕上还是在变量中?
  • 在一个变量中。如果这样更容易的话,我也可以使用平面文件。
  • 我已经开始考虑使用这篇文章中的一些想法:stackoverflow.com/questions/16396873/popen-mixed-data-stream
  • 我看到这些方法的问题是它们不是为真正的“快速”流而设计的,而且似乎没有对事件顺序的精确控制。我正在轮询的过程可以闪电般快速地工作并在两个流上转储消息。使用任意睡眠,以及来自 sdtout 和 stderr 的 readline() 可以给我一个很好的消息顺序近似值,但它并不完美,将两个流重定向到同一个文件描述符的方式将是。 (假设每次写入时都会发生刷新,我认为确实如此......)
  • 我可以使用 popen 的替代方法,或者 shell 命令重定向流的某种组合。按顺序组合这些消息是一项常见且典型的任务。我觉得应该有一种干净简单的方法来检测是否有任何东西通过 stderr 流...

标签: python stdout popen stderr


【解决方案1】:

首先,我通过深入研究生成流的过程,在很大程度上解决了我的实际用例。我正在使用 MySQL 客户端,并发现命令行开关的正确组合可以解决真正的目标。我会省略它,因为它完全针对那种情况。

然而,在我发现它之前,我确实找到了一个非常有用的探索方向 - 使用“Tee”程序和/或 Python 源等价物。我没有尝试实现它,但它似乎是一种可以用来同时从 stdout 和 stderr 收集输出的方法,同时只将 stdout 发送到另一个文件描述符。如果两个输出不相同,那么这将告诉您是否使用了 stderr。

退房:

https://www.computerhope.com/unix/utee.htm

还有:

Python subprocess get children's output to file and terminal?

【讨论】:

  • 在想到您的问题时,我想到了tee。但是,它会导致与所有其他解决方案相同的问题。它可能会更改您的流的顺序。 stdou 和 stderr 是独立的流。将它们重定向到同一流不会给出固定的顺序,而是取决于操作系统的当前状态及其其他操作。将tee 添加到组合中可能会更改此顺序,因此不能保证给出相同的结果。但是,如果您对 stdoutstderr 的顺序有内在了解,则可以将其合并到带有或不带有 tee 的工作解决方案中。
  • 这很有意义。谢谢@JohanL。至少在我的用例中,我为 MySQL 客户端找到了一个开关,即--unbuffered,它在每次写入它们时强制刷新 stdout/stderr,从而解决了这个确切的问题(大概是出于这个确切的原因)。当然,这对于无法控制的其他过程无济于事......
猜你喜欢
  • 2011-08-20
  • 2023-04-06
  • 2013-06-18
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 2011-04-18
  • 2022-12-07
相关资源
最近更新 更多