Bash中的管道:一次一个(逐行)或全部一次

时间:2018-04-06 05:07:30

标签: linux bash shell unix

$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)

首先,我创建了5个文件

$ touch a b c d e
$ ls
a  b  c  d  e

在以下示例中,xargs似乎同时通过管道获取find的所有结果:

$ find . -type f | xargs -t echo | wc -w
echo ./c ./b ./a ./d ./e
5

在以下示例中,xargs似乎一次通过管道获取find的所有结果(逐行):

$ find . -type f | xargs -t -i mv {} {}.bak | wc  -w
mv ./c ./c.bak
mv ./b ./b.bak
mv ./a ./a.bak
mv ./d ./d.bak
mv ./e ./e.bak
0

在以下示例中,xargs似乎一次通过管道获取“find”的所有结果(逐行);并且wc似乎同时通过管道xargs获取所有结果。

否则,如果wc逐行获得结果,您会看到1在结尾处出现5次而不是5

$ find . -type f | xargs -t -i echo {} | wc -w
echo ./e.bak
echo ./b.bak
echo ./c.bak
echo ./a.bak
echo ./d.bak
5

管道是否一次从前一个命令(逐行)或全部一次获得结果?

2 个答案:

答案 0 :(得分:2)

您正在观察的行为来自您正在使用的xargs选项。 -i选项专门指示xargs为每个输入令牌创建一个新进程,并用该令牌替换{}占位符。

管道本身没有规定任何具体行为;许多内核一次会传递一个完整的I / O缓冲区(因此有很多关于I / O缓冲管道的问题,当“实际症状正好”时,“这个命令似乎没有在管道中做任何事情”输出缓冲区尚未满。)

答案 1 :(得分:1)

|只需将stdout从流程传递到下一个流程的stdin即可。例如,find . -type f | grep "bla"转换为(粗略地):运行find . -type f,无论此过程打印到stdout,将其原样传递给grep "bla"作为标准输入。

由接收过程决定如何处理它。 xargs在每一行应用给定的替换。另一方面,wc跟踪各种统计数据(单词,行等),直到没有更多输入,然后打印出来。

阅读stdout,stdin等可能很有用 - http://www.learnlinux.org.za/courses/build/shell-scripting/ch01s04.html

相关问题