【问题标题】:Does linux pipe (|) always block?linux管道(|)总是阻塞吗?
【发布时间】:2020-04-04 15:20:08
【问题描述】:

我想将 2 个 linux 命令链接在一起,以便命令 1 可以不断地将数据传递/流式传输到命令 2。在我的情况下,命令 1 生成一个(逐行)数据库导出,我想通过管道传输in 到命令 2(它将调用一个函数将每个数据导出行写入一个新的数据库)。

例如

 command 1 | command 2 

这个基于 Phyton 的解决方案看起来很不错,但也有阻塞,而且在它全部可用之后,它只是逐行读取粗壮的..How to pipe input to python line by line from linux program?

作为背景,我正在尝试导出 10 TB Cassandra db,我可以使用 dsbulk 来完成。我的想法/偏好是不建立 10 TB 的导出然后处理它,我想“在飞行中”处理它

任何指针表示赞赏,谢谢。

【问题讨论】:

  • 您链接到的问题是使用 xargs,在这种情况下没有任何意义。只需使用sys.stdin 读取函数或普通input() 来读取来自该管道的数据。一旦管道的上一个命令完成,Python 将在 input() 上引发 EOFError。
  • 感谢您的回复。根据你所描述的,你认为这会解决我的问题吗?你描述的 input() 函数何时/如何被调用?好的,它是一个 Python 脚本,所以我们有类似的东西:dsbulk params.... | python perist_each_record_viaRead ?整个事情仍然阻塞,对吗?
  • 我取决于读者。如果读取过程在进行任何处理之前尝试读取所有数据,那么您可能会遇到问题。如果阅读器设计得很好,它不会在进行任何处理之前尝试读取所有数据。
  • 对管道的操作可能会阻塞,但询问管道是否阻塞甚至没有意义。

标签: linux


【解决方案1】:

source.py

for i in range(1000):
    print("Test", i)

dest.py

import sys

for line in sys.stdin:
    print(line.swapcase().strip())

然后尝试类似python3 source.py | python3 dest.py

【讨论】:

  • 这很有趣。当我将外部范围增加到 1000000000 时,它会清楚地看到从命令 1 到命令 2 的数据“流式传输”,我认为这回答了我的问题,并且管道命令默认情况下不会阻塞?还是有点迷茫。
  • 管道本身最多缓冲 64 KiB,但 xargs your_program 在启动程序之前读取整个输入,因为它必须将所有输入作为命令行参数 sys.argv 传递给您的程序。跨度>
  • 所以在上面的例子中,dest.py 是否必须在调用/开始工作之前读取整个输入(即 source.py 的输出)?
  • 好的,所以我看到了阻塞。 (我已将 source.py 更新为每次打印时休眠 1 秒,而 dest.py 仅在 source.py 完成后接收数据)。一切都很好,但我觉得我在第一方。我有一个命令会产生大约 10 TB 的文本。我需要第二个命令来尽快开始接收,因为标准输入当然不能处理 10 TB。
  • 如果你在 dest.py 的 for 循环中进行处理,只有一点点被缓冲。如果 dest.py 中的处理速度较慢,打印将阻止(减慢)source.py 的运行以匹配。如果 source 速度较慢,dest.py 中的循环将运行得更慢(stdin 读取块直到有更多输入)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-02
  • 2011-12-05
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 2016-06-05
相关资源
最近更新 更多