$ 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
管道是否一次从前一个命令(逐行)或全部一次获得结果?
答案 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