我对此非常困惑。需要一些澄清。
示例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从标准输入读取项目,由空格分隔(可以是 用双引号或单引号或反斜杠或换行符保护,和 使用any执行命令(默认为/ bin / echo)一次或多次 初始参数后跟从标准输入读取的项目。空白行 标准输入被忽略。
答案 0 :(得分:45)
一般来说 xargs 就像这样使用
prog | xargs utility
其中prog
预计输出一个或多个换行符/空格分隔结果。诀窍是xargs
不一定为每个结果调用utility
一次,而是将结果拆分为子列表并为每个子列表调用utility
。如果您想强制xargs为每个结果调用utility
,您需要使用xargs -L1
调用它。
请注意,xargs
承诺发送给utility
的子列表短于ARG_MAX
(如果您感到好奇,可以使用ARG_MAX
获取当前值getconf ARG_MAX
{{1}}。)这就是它避免那些可怕的“Argument list to long”错误的方法。
答案 1 :(得分:9)
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之间没有管道。
答案 2 :(得分:7)
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
将导致:
$ cmd1 -a -b line1 line2 line3 ... lineN
如果行数太大, xargs
会将cmd1 ...
分成几个cmd1
的执行。
xargs
可用于与将stdin
行作为位置参数传递相关的许多其他任务。查看xargs(1)中的大写-P
选项,以便并行运行多个命令实例。
答案 3 :(得分:2)
xargs通常用于将参数组合在一起,这样当你将大量参数传递给命令时就不会出现“太多参数”错误
答案 4 :(得分:2)
#!/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个参数