Linux管道行为

时间:2017-05-18 09:49:07

标签: linux shell pipe stdout stdin

好的,这只是为了满足我的好奇心和其他可能有类似问题的人。请承担无知和冗长的问题,因为它部分是“我不知道我不知道的事情”。

第1节

假设fileToFollow.txt具有一些任意内容。

row1
row2
row3

执行tail fileToFollow.txt | cat会产生预期的文件内容。

执行tail -f fileToFollow.txt | cat将继续输出写入fileToFollow.txt

的任何内容

我将管道设想为获取一个程序的输出并将其输入另一个程序的输入(例如,如果cat是一个C程序,它将能够通过main()参数访问该输入)。

问题1:这里有什么问题,每次尾巴都有输出时才会调用cat?

第2节

我决定将grep投入混音设置以下内容:

tail -f fileToFollow.txt | grep "whatever" | cat

显然,这里不需要cat,因为grep本身无论如何输出到终端。但考虑到管道从一个程序输出到另一个程序输入的想法,我认为它会。但是,在这种情况下,终端中不显示输出。

以下当然可行:

tail -f fileToFollow.txt | grep "whatever"

我有一种预感,我对管道如何实际工作以及为什么我提出的案例表现不像我期望的那样有点困惑。

欢迎任何形式的启蒙。非常感谢花时间。

2 个答案:

答案 0 :(得分:1)

当您输入程序时,源的标准输出通常会切换到缓冲模式(参见man setvbuf()),这意味着必须先生成一定数量的数据(2KiB或4KiB左右)才能生成将被提交给write(2)

将它赋予tty使用行缓冲模式,以便在\n之后刷新缓冲区。

有一个stdbuf工具可以修改此行为。

答案 1 :(得分:1)

对问题1的回答:不,猫一直在作为一个过程运行,但是在没有任何可用的情况下它被阻止读取标准输入。当管道中的进程(尾部)将新字节写入管道时,读取调用将返回,并且cat能够处理新数据。之后,它将再次读取并阻止,直到有新数据可用。