简体   繁体   English

管道如何在Linux中运行?

[英]How does a pipe work in Linux?

How does piping work? 管道如何工作? If I run a program via CLI and redirect output to a file will I be able to pipe that file into another program as it is being written? 如果我通过CLI运行程序并将输出重定向到文件,我可以将该文件传输到另一个程序中吗?

Basically when one line is written to the file I would like it to be piped immediately to my second application (I am trying to dynamically draw a graph off an existing program). 基本上,当一行写入文件时,我希望它立即通过管道输送到我的第二个应用程序(我试图从现有程序中动态绘制图形)。 Just unsure if piping completes the first command before moving on to the next command. 在转到下一个命令之前,只是不确定管道是否完成了第一个命令。

Any feed back would be greatly appreciated! 任何反馈将不胜感激!

If you want to redirect the output of one program into the input of another, just use a simple pipeline: 如果要将一个程序的输出重定向到另一个程序的输入,只需使用一个简单的管道:

program1 arg arg | program2 arg arg

If you want to save the output of program1 into a file and pipe it into program2 , you can use tee(1) : 如果要将program1的输出保存到文件中并将其传送到program2 ,可以使用tee(1)

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

All programs in a pipeline are run simultaneously. 管道中的所有程序都是同时运行的。 Most programs typically use blocking I/O: if when they try to read their input and nothing is there, they block : that is, they stop, and the operating system de-schedules them to run until more input becomes available (to avoid eating up the CPU). 大多数程序通常使用阻塞 I / O:如果他们尝试读取输入并且没有任何内容,则阻止 :即停止,操作系统取消调度它们直到有更多输入可用(以避免进食) CPU)。 Similarly, if a program earlier in the pipeline is writing data faster than a later program can read it, eventually the pipe's buffer fills up and the writer blocks: the OS de-schedules it until the pipe's buffer gets emptied by the reader, and then it can continue writing again. 类似地,如果管道中较早的程序写入数据的速度比后来的程序读取的速度快,那么管道的缓冲区最终会填满并且编写器阻塞:操作系统将其解除调度,直到管道的缓冲区被读取器清空,然后它可以继续写作。


EDIT 编辑

If you want to use the output of program1 as the command-line parameters, you can use the backquotes or the $() syntax: 如果要使用program1的输出作为命令行参数,可以使用反引号或$()语法:

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

# Same as above
program2 $(program1 arg)

The $() syntax should be preferred, since they are clearer, and they can be nested. $()语法应该是首选的,因为它们更清晰,并且可以嵌套。

Piping does not complete the first command before running the second . 在运行第二个命令之前,管道不会完成第一个命令 Unix (and Linux) piping run all commands concurrently. Unix(和Linux)管道同时运行所有命令。 A command will be suspended if 如果命令将被暂停

  • It is starved for input. 它缺乏投入。

  • It has produced significantly more output than its successor is ready to consume. 它产生的产量远远超过其后续产品的消费量。

For most programs output is buffered , which means that the OS accumulates a substantial amount of output (perhaps 8000 characters or so) before passing it on to the next stage of the pipeline. 对于大多数程序,输出是缓冲的 ,这意味着OS在将其传递到管道的下一个阶段之前会累积大量输出(可能大约8000个字符)。 This buffering is used to avoid too much switching back and forth between processes and kernel. 此缓冲用于避免在进程和内核之间来回切换太多。

If you want output on a pipeline to be sent right away, you can use unbuffered I/O, which in C means calling something like fflush() to be sure that any buffered output is immediately sent on to the next process. 如果您希望立即发送管道上的输出,您可以使用无缓冲的 I / O,在C中意味着调用fflush()类的东西以确保任何缓冲的输出立即发送到下一个进程。 Unbuffered input is also possible but is generally unnecessary because a process that is starved for input typically does not wait for a full buffer but will process any input you can get. 无缓冲输入也是可能的,但通常是不必要的,因为缺乏输入的进程通常不会等待完整的缓冲区,但会处理您可以获得的任何输入。

For typical applications unbuffered output is not recommended; 对于典型应用,不建议使用无缓冲输出; you generally get the best performance with the defaults. 通常使用默认值获得最佳性能。 In your case, however, where you want to do dynamic graphing immediately the first process has the info available, you definitely want to be using unbuffered output. 但是,在您的情况下,您希望立即执行动态绘图,第一个进程具有可用信息,您肯定希望使用无缓冲输出。 If you're using C, calling fflush(stdout) whenever you want output sent will be sufficient. 如果你正在使用C,那么只要你想要输出就调用fflush(stdout)就足够了。

If your programs are communicating using stdin and stdout , then make sure that you are either calling fflush(stdout) after you write or find some way to disable standard IO buffering. 如果您的程序正在使用stdinstdout进行通信,那么请确保在编写后调用fflush(stdout)或找到某种方法来禁用标准IO缓冲。 The best reference that I can think of that really describe how to best implement pipelines in C/C++ is Advanced Programming in the UNIX Environment or UNIX Network Programming: Volume 2 . 我能想到的最好的参考是真正描述如何在C / C ++中最好地实现管道的是UNIX环境中的高级编程UNIX网络编程:第2卷 You could probably start with a this article as well. 你也许可以从这篇文章开始。

If your two programs insist on reading and writing to files and do not use stdin/stdout, you may find you can use a named pipe instead of a file. 如果您的两个程序坚持读取和写入文件而不使用stdin / stdout,您可能会发现可以使用命名管道而不是文件。

Create a named pipe with the mknod(1) command: 使用mknod(1)命令创建命名管道:

$ mknod /tmp/named-pipe p

Then configure your programs to read and write to /tmp/named-pipe (use whatever path/name you feel is appropriate). 然后将程序配置为读取和写入/ tmp / named-pipe(使用您认为合适的路径/名称)。

In this case, both programs will run in parallel, blocking as necessary when the pipe becomes full/empty as described in the other answers. 在这种情况下,两个程序将并行运行,当管道变满/空时根据需要阻塞,如其他答案中所述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM