【发布时间】:2018-01-14 21:23:57
【问题描述】:
我一直在处理一个我找不到解决方法的奇怪问题。
我的情况如下。
我在 python 中有一个名为“app1”的应用程序,它需要一个文件来输出它的执行结果。
我有一个名为“app2”的辅助应用程序;一个二进制文件,从标准输入获取输入。
我想将“app1”生成的内容直接传送到“app2”中进行处理,理想情况下应该是这样的:
app1 | app2
但是,正如我所说,有一些限制,例如 app1 需要一个文件作为输出。 我发现的第一个“欺骗”app1 输出到 stdout 的解决方案是使用 mkfifo 并创建一个管道,这样我就可以将它通过管道传输到 app2 中的 stdin 中。像这样:
pipe='/tmp/output_pipe'
mkfifo "$output_pipe"
python app1 -o "$output_pipe" &
app2 < $tmp_pipe
问题在于,最终,在执行过程中,app1 将生成比 app2 可以处理的输入更多的输出,并且由于管道上的缓冲区大小限制,管道将被填满一切都会停止工作。
然后我使用了另一种方法:
python app1 -o /dev/stdout | app2
但情况与标准输出相同,也有缓冲区大小限制。
有人知道我该如何解决这个特定的场景吗?
TL;DR:我需要一个“虚拟”文件作为标准输出,但没有管道的标准尺寸限制。
【问题讨论】:
-
听起来您遇到了需要解决的死锁问题。创建更大的管道并不是最好的解决方案。
-
特别是,“管道将被填满,一切都将停止工作”的说法没有多大意义。如果管道填满,则 app1 将阻止写入,但 app2 应继续工作。当它从管道中清除数据时,app1 将开始写入更多数据。除非你有其他你没有描述的死锁。
-
我的推断是因为如果我尝试使用缓冲管道,运行几个小时后,app2 将停止工作。如果我使用无缓冲管道(如 stderr),应用程序会持续运行数小时而不会出现问题。这是我(可能是错误的)扣除的唯一原因。
标签: linux bash pipe buffer stdout