我对此非常困惑。需要一些澄清。
例1:
pgrep string | xargs ps
例2:
find . | xargs grep whatever
从例1开始,我就是这样收集的:
搜索一个“字符串”,它是正在运行的进程名称的一部分,并将所有匹配的进程ID返回给'xargs ps' - >,它只是将ps附加到匹配项(它们是process-id本身)以获得相同的输出为:
ps <processid>
有人能解释一下xargs在这种情况下的真正作用吗?
从例2开始,我就是这样收集的:
它是从当前工作目录中递归搜索一些“字符串”。在这里,'xargs'究竟是如何工作的?
我认为'xargs'反复将标准输入的数据附加到给予xargs(通常是UNIX命令本身)的'参数'。
来自xargs()手册页:
xargs从标准输入中读取项目,由空格分隔(可以使用双引号或单引号或反斜杠保护)或换行符,并使用任何初始参数执行命令(默认为/ bin / echo)一次或多次从标准输入读取的项目。标准输入上的空行将被忽略。
通常,xargs就像这样使用
prog | xargs utility
其中prog
预计输出一个或多个换行符/空格分隔结果。诀窍是xargs
不一定为每个结果调用utility
一次,而是将结果拆分为子列表并为每个子列表调用utility
。如果你想强制xargs为每个结果调用utility
,你需要使用xargs -L1
调用它。
请注意,xargs
向您承诺发送到utility
的子列表比ARG_MAX
短(如果您很好奇,可以使用ARG_MAX
获取getconf ARG_MAX
的当前值。)这就是它避免那些可怕的“Argument list to long”错误的方法。
xargs的一个很好的例子就是尝试使用find为目录中的每个文件获取已排序的校验和。
find . | cksum | sort
只返回一个校验和,并且不清楚它的校验和是什么。不是我们想要的。管道将stdout从find发送到stdin用于cksum。 cksum真正想要的是一个命令行参数列表,例如:
cksum file001.blah file002.blah file003.blah
将报告三行,每个文件一行,带有所需的校验和。 Xargs做了一个神奇的技巧 - 将前一个程序的stdout转换为临时和隐藏的命令行以提供给下一个程序。有效的命令行是:
find . | xargs cksum | sort
注意xargs和cksum之间没有管道。
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
将导致:
$ cmd1 -a -b line1 line2 line3 ... lineN
如果线数太大,xargs
将把cmd1 ...
分成几次执行cmd1
。
xargs
可用于与将stdin
线作为位置参数传递相关的许多其他任务。查看-P
中的首都xargs(1)选项,以便并行运行多个命令实例。
xargs通常用于将参数组合在一起,这样当您将大量参数传递给命令时,就不会出现“太多参数”错误
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a
done
命令
$sh myscript 1 2 3 4 5
会屈服
1
2
3
4
5
但
$sh myscript 1 2 3 4 5 6 7 8 9 10 11
由于超出了最大参数数量,因此无法正常工作(我实际上并不确定最大值是多少,但在这个例子中可以说它是10!)
为了解决这个问题,我们可以使用
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a | xargs echo
done
我们可以像这样运行它
$sh myscript "1 2 3 4 5" "6 7 8 9 10 11"
因为只有2个参数,所以得到正确的结果