了解UNIX命令xargs

问题描述 投票:25回答:5

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

例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)一次或多次从标准输入读取的项目。标准输入上的空行将被忽略。

unix xargs
5个回答
46
投票

通常,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”错误的方法。


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之间没有管道。


7
投票
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b

将导致:

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

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

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


2
投票

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


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个参数,所以得到正确的结果

© www.soinside.com 2019 - 2024. All rights reserved.