管道如何在Linux中运行?

时间:2009-07-02 02:25:47

标签: c linux redirect pipe

管道如何工作?如果我通过CLI运行程序并将输出重定向到文件,我可以将该文件传输到另一个程序中吗?

基本上,当一行被写入文件时,我希望它能够立即传送到我的第二个应用程序(我试图从现有程序中动态绘制图形)。在转到下一个命令之前,只是不确定管道是否完成了第一个命令。

非常感谢任何反馈!

4 个答案:

答案 0 :(得分:56)

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

program1 arg arg | program2 arg arg

如果您想将program1的输出保存到文件中并将其保存到program2,您可以使用tee(1)

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

管道中的所有程序都是同时运行的。大多数程序通常使用阻止 I / O:如果他们试图读取他们的输入而没有任何东西,他们阻止:也就是说,他们停止了,操作系统de - 安排它们运行,直到有更多输入可用(以避免吃掉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)

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

答案 1 :(得分:26)

管道在运行第二个之前未完成第一个命令。 Unix(和Linux)管道同时运行所有命令。如果

,命令将被暂停
  • 缺乏投入。

  • 它产生的产量远远超过其后续产品的消费量。

对于大多数程序,输出是缓冲,这意味着OS在将其传递到管道的下一个阶段之前会累积大量输出(可能大约8000个字符)。此缓冲用于避免在进程和内核之间来回切换太多。

如果您希望立即发送管道上的输出,您可以使用无缓冲 I / O,在C中意味着调用类似fflush()的内容以确保任何缓冲输出是立即发送到下一个进程。无缓冲输入也是可能的,但通常是不必要的,因为缺乏输入的进程通常不会等待完整缓冲区,但会处理您可以获得的任何输入。

对于典型应用,不建议使用无缓冲输出;通常使用默认值获得最佳性能。但是,在您的情况下,您希望立即执行动态绘图,第一个进程具有可用信息,您肯定希望使用无缓冲输出。如果你正在使用C,那么只要你想要输出就调用fflush(stdout)就足够了。

答案 2 :(得分:9)

如果您的程序正在使用stdinstdout进行通信,请确保在编写后调用fflush(stdout)或找到某种方法来禁用标准IO缓冲。我能想到的最佳参考实际上描述了如何在C / C ++中最好地实现管道是Advanced Programming in the UNIX EnvironmentUNIX Network Programming: Volume 2。你也许可以从this article开始。

答案 3 :(得分:3)

如果您的两个程序坚持读取和写入文件而不使用stdin / stdout,您可能会发现可以使用命名管道而不是文件。

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

$ mknod /tmp/named-pipe p

然后将程序配置为读取和写入/ tmp / named-pipe(使用您认为合适的路径/名称)。

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