如何做一个管道在Linux下工作吗?(How does a pipe work in Linux?)

2019-06-24 17:36发布

如何管工作? 如果我运行通过CLI程序并重定向输出到一个文件,我将能够在该文件到另一个程序管,因为它正在写的?

基本上,当一个行写入文件,我想它被立即输送到我的第二个应用程序(我试图动态绘制图形关闭现有的程序)。 只是不确定的,如果管道上移动到下一个命令之前完成第一个命令。

任何反馈将不胜感激!

Answer 1:

如果你想要一个程序的输出重定向到另一个输入,只需使用一个简单的管道:

program1 arg arg | program2 arg arg

如果您想要的输出保存program1到一个文件管道将它导入program2 ,您可以使用tee(1)

program1 arg arg | tee output-file | program2 arg arg

在管道中的所有程序同时运行。 大多数程序通常使用阻塞 I / O:如果当他们尝试读取输入和无所不有,他们阻止 :也就是说,他们停止和操作系统去安排它们运行到更多的输入可用(避免食用了CPU)。 同样,如果早在管道中的程序写入数据比后面的程序更快的可以读取它,最终管道缓冲区填满和作家块:操作系统去安排它,直到管道缓冲区得到由读者清空,然后它可以再继续写。


编辑

如果您想使用的输出program1作为命令行参数,你可以使用反引号或$()语法:

# Runs "program1 arg", and uses the output as the command-line arguments for
# program2
program2 `program1 arg`

# Same as above
program2 $(program1 arg)

$()语法应该是首选,因为它们更清晰,并且它们可以被嵌套。



Answer 2:

管道不运行第二前完成第一个命令 。 UNIX(和Linux)管道并行运行的所有命令。 一个命令将被暂停,如果

  • 它是饿死的输入。

  • 它产生了显著更多的输出比其继任者准备消费。

对于大多数程序输出进行缓冲 ,这意味着在OS上传递到流水线的下一个阶段之前累积输出(可能是8000个字符或左右)的一个显着量的。 这种缓冲用来避免过于进程和内核之间没有太大来回切换。

如果你想在一个管道输出马上发送,您可以使用无缓冲 I / O,这在C表示调用像fflush()以确保任何缓冲的输出被立即发送到下一个工序。 无缓冲输入也是可能的,但一般是不必要的,因为被饿死输入的过程通常不会等待一个完整的缓冲区,但会处理任何输入就可以得到。

对于典型的应用中不推荐使用无缓冲输出; 你通常得到与默认的最佳性能。 在你的情况,但是,要做到动态图形立即在第一过程有信息可用,你一定要使用无缓冲输出为。 如果你使用C,调用fflush(stdout) ,只要你想发送的输出就足够了。



Answer 3:

如果你的程序正在使用的通信stdinstdout ,然后确保你要么调用fflush(stdout)你写后还是找到了一些方法来禁用标准IO缓冲。 我能想到的,真介绍了如何最好地实现用C管道的最佳参考/ C ++是在UNIX环境高级编程或UNIX网络编程:第2卷 。 你也许可以用开始这篇文章也是如此。



Answer 4:

如果你的两个方案坚持读取和写入文件,不使用标准输入/输出,你会发现你可以用它代替文件的命名管道

创建使用mknod(1)命令,命名管道:

$ mknod /tmp/named-pipe p

然后配置你的程序读取和写入到/ tmp /命名管道(使用任何路径/名称,你觉得是合适的)。

在这种情况下,这两个程序将在并行地运行,阻塞时,根据需要在其他的答案中描述的管变满/空。



文章来源: How does a pipe work in Linux?