了解UNIX命令xargs

时间:2009-12-13 22:31:25

标签: unix xargs

我对此非常困惑。需要一些澄清。

示例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)一次或多次   初始参数后跟从标准输入读取的项目。空白行   标准输入被忽略。

5 个答案:

答案 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个参数