Linux Bash中的管道:一次一个(逐行)或一次全部
首先,我创建了5个文件Linux Bash中的管道:一次一个(逐行)或一次全部,linux,bash,shell,unix,Linux,Bash,Shell,Unix,首先,我创建了5个文件 $ bash --version GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu) 在以下示例中,xargs似乎可以通过管道一次获得find的所有结果: 在以下示例中,xargs似乎通过管道一次(逐行)获取find的所有结果: 在下面的示例中,xargs似乎通过管道一次(逐行)获取“find”的所有结果;而wc似乎可以通过管道一次获得xargs的所有结果 否则,如果wc逐行获得结果,您将看到1出现
$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
在以下示例中,xargs
似乎可以通过管道一次获得find
的所有结果:
在以下示例中,xargs
似乎通过管道一次(逐行)获取find
的所有结果:
在下面的示例中,xargs
似乎通过管道一次(逐行)获取“find”的所有结果;而wc
似乎可以通过管道一次获得xargs
的所有结果
否则,如果wc
逐行获得结果,您将看到1
出现5次,而不是最后出现5
$ 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
那么管道是从上一个命令一次(一行接一行)还是一次全部获取结果呢?
只是将stdout
从一个进程传递到下一个进程的stdin
。例如,find-键入f | grep“bla”
转换为(大致):Runfind-键入f,无论该过程打印到stdout的内容是什么,都将其作为stdin传递给grep“bla”
由接收流程决定如何处理它xargs
在每一行上应用给定的替换<另一方面,code>wc会跟踪各种统计信息(字、行等),直到没有更多输入,然后打印出来
阅读stdout、stdin等可能很有用。-您正在观察的行为来自您正在使用的
xargs
选项。-i
选项专门指示xargs
为每个输入令牌创建一个新进程,并用该令牌替换{}
占位符
管道本身没有规定任何具体行为;许多内核一次会传递一个完整的I/O缓冲区(因此,关于使用管道进行I/O缓冲的问题很多,当实际症状只是输出缓冲区还没有满时,“此命令似乎在管道中没有做任何事情”。这听起来是一个合理的解释。由管道后面的
命令决定如何使用上一个命令(进程)传递的数据。因此,看起来数据有时是逐行处理的,有时是一次性处理的(如wc
示例所示)。find-键入f | xargs-t-i echo{}| xargs-t echo
此命令演示您编写的内容是正确的-i
更改xargs
的行为。是的,完全正确。(顺便说一句,xargs
的默认操作是echo
,因此您实际上不需要把它拼出来。)第一个xargs
按您的要求一次打印一个,第二个将它们全部收集回一行,哪个是xargs
的主要用例。它是否也意味着xargs-t echo
实际上用空格替换每个结果后的所有换行符?而cat
保留换行符,如find中所示-输入f | xargs-t-i echo{}| cat
同样,xargs
的主要目的是在生成的命令的命令行上收集尽可能多的参数。当echo
在其argv
数组中接收这五个参数时,空格由echo
提供。
$ find . -type f | xargs -t echo | wc -w
echo ./c ./b ./a ./d ./e
5
$ 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
$ 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