了解UNIX命令xargs

hal*_*i0n 28 unix xargs

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

例1:

pgrep string | xargs ps
Run Code Online (Sandbox Code Playgroud)

例2:

find . | xargs grep whatever
Run Code Online (Sandbox Code Playgroud)

从例1开始,我就是这样收集的:

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

ps <processid>
Run Code Online (Sandbox Code Playgroud)

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

从例2开始,我就是这样收集的:

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

我认为'xargs'反复将标准输入的数据附加到给予xargs(通常是UNIX命令本身)的'参数'.

来自xargs()手册页:

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

Lar*_*ann 48

通常,xargs就像这样使用

prog | xargs实用程序

其中PROG预期输出一个或多个换行/空间分离结果.诀窍是xargs没有!对每个结果一次调用实用程序,而是将结果列表拆分为子列表,并为每个子列表调用实用程序.如果要强制xargs 为每个结果调用实用程序,则需要使用xargs -L1调用它.

请注意,xargs承诺发送给实用程序的子列表比ARG_MAX短(这就是它避免那些可怕的Argument列表到长错误的方式).您可以使用getconf ARG_MAX获取ARG_MAX的当前值

  • 考虑这个命令"find/etc -type d -depth 1 | xargs echo",它打印/ etc文件夹中的所有目录(但不打印它们的子目录).由于echo采用多个参数,因此结果是一个长行"/ etc/dir1/etc/dir2 ...".如果您改为调用"find/etc -type d -depth 1 | xargs -L1 echo",则会为每个结果调用一次echo,从而导致/ etc中的每个目录单独打印在一行上. (7认同)

Dar*_*enW 10

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

find . | cksum  | sort
Run Code Online (Sandbox Code Playgroud)

只返回一个校验和,并且不清楚它的校验和是什么.不是我们想要的.管道将stdout从find发送到stdin用于cksum.cksum真正想要的是一个命令行参数列表,例如

cksum file001.blah file002.blah  file003.blah
Run Code Online (Sandbox Code Playgroud)

将报告三行,每个文件一行,带有所需的校验和.Xargs做了一个神奇的技巧 - 将前一个程序的stdout转换为临时和隐藏的命令行以提供给下一个程序.有效的命令行是:

find . | xargs cksum | sort
Run Code Online (Sandbox Code Playgroud)

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

  • 顺便说一句,这是我在两个或多个目录中查找重复文件的秘诀的主要成分,即使它们的名称不同。 (2认同)

And*_*ikh 8

$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
Run Code Online (Sandbox Code Playgroud)

将导致:

$ cmd1 -a -b line1 line2 line3 ... lineN
Run Code Online (Sandbox Code Playgroud)

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

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