33

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

示例 1:

pgrep string | xargs ps

示例 2:

find . | xargs grep whatever

从示例 1 中,我收集它是这样的:

搜索“字符串”,它是运行进程名称的一部分,并将所有匹配项的进程 ID 返回到“xargs ps”-> 它只是将 ps 附加到匹配项(它们本身是进程 ID)以获得相同的输出为:

ps <processid>

有人可以解释 xargs 在这种情况下的真正作用吗?

从示例 2 中,我收集它是这样的:

它是从当前工作目录中递归搜索一些“字符串”。在这里,“xargs”究竟是如何工作的?

我认为“xargs”反复将标准输入中的数据附加到给 xargs 的“参数”(通常它本身就是一个 UNIX 命令)。

从 xargs() 手册页:

xargs 从标准输入中读取项目,由空格(可以用双引号或单引号或反斜杠保护)或换行符分隔,并执行命令(默认为 /bin/echo)一次或多次,后面跟着任何初始参数通过从标准输入读取的项目。标准输入上的空行被忽略。

4

5 回答 5

56

一般来说xargs是这样使用的

prog | xargs utility

whereprog预计会输出一个或多个换行符/空格分隔的结果。诀窍是xargs不一定utility为每个结果调用一次,而是将结果拆分为子列表并调用utility每个子列表。如果要强制 xargs 调用utility每个结果,则需要使用xargs -L1.

请注意,它xargs向您保证发送到的子列表utility短于ARG_MAX(如果您好奇,可以获取ARG_MAXusing的当前值getconf ARG_MAX。)这就是它避免那些可怕的“参数列表变长”错误的方法。

于 2009-12-14T19:12:06.127 回答
14

xargs 所做的一个很好的例子是尝试使用 find 为目录中的每个文件获取排序校验和。

find . | cksum  | sort

只返回一个校验和,不清楚它的校验和是什么。不是我们想要的。管道将标准输出从 find 发送到标准输入以获取 cksum。cksum 真正想要的是一个命令行参数列表,例如

cksum file001.blah file002.blah  file003.blah

将报告三行,每个文件一行,并带有所需的校验和。Xargs 做了魔术 - 将前一个程序的标准输出转换为临时和隐藏的命令行以提供给下一个程序。有效的命令行是:

find . | xargs cksum | sort

注意 xargs 和 cksum 之间没有管道。

于 2009-12-13T22:46:39.390 回答
8
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b

将导致:

$ cmd1 -a -b line1 line2 line3 ... lineN

xargs如果行数太大,将cmd1 ...分成几次执行。cmd1

xargs可用于与将stdin行作为位置参数传递相关的许多其他任务。查看xargs(1)中用于并行运行多个命令实例的 capital-P选项。

于 2009-12-13T22:41:26.267 回答
4
#!/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 个参数

于 2009-12-13T22:43:21.493 回答
2

xargs 通常用于将参数组合在一起,这样您就不会在将大量参数传递给命令时出现“参数过多”错误

于 2009-12-13T22:35:26.947 回答