GNUxargs
有选项'-x'。手册页说:
-x 如果超出大小(参见 -s 选项)则退出。
但xargs
似乎不在乎是否-x
设置。我一直无法举一个例子,其中-x
根本没有任何影响。
请提供两个示例,其中唯一的区别是添加-x
并产生不同的输出。
你必须设置一个大小来测试你是否超过了它。
$ echo -e "12\n1234"
12
1234
$ echo -e "12\n1234" | xargs echo
12 1234
$ echo -e "12\n1234" | xargs -x echo # no effect
12 1234
$ echo -e "12\n1234\n13" | xargs -s 8 echo # process valid args until an error occurs
xargs: argument line too long
12
$ echo -e "12\n1234" | xargs -s 8 -x echo # error and exit
xargs: argument line too long
我仍然无法解释为什么这会给出 1 - 11:
(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 echo
但这给出了 1 - 9:
(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 -x echo
-x
总是只给出一行的差异(即那行太长)?
这当然取决于xargs
您使用的类型,但是流行的 GNU findutils' xargs
(很可能是您所拥有的)具有这种行为,违反了最小惊讶原则:它通过反复在内存中累积命令行读取下一个输入项并将其附加到现有命令行,直到它不适合行长度......现在,它检查读取的项目是否甚至不适合作为单个参数的行(情况就是这样)echo 1234111
在你的例子中):
if (p >= endbuf)
{
exec_if_possible ();
error (EXIT_FAILURE, 0, _("argument line too long"));
}
(上面的代码read_line()
在 findutils-4.6.0/xargs/xargs.c 中接近函数末尾,在 findutils-4.4.2 中几乎相同)
static void
exec_if_possible (void)
{
if (bc_ctl.replace_pat || initial_args ||
bc_state.cmd_argc == bc_ctl.initial_argc || bc_ctl.exit_if_size_exceeded)
return;
bc_do_exec (&bc_ctl, &bc_state);
}
这是 option -x
(对应于bc_ctl.exit_if_size_exceeded
)产生影响的地方 - with -x
, exec_if_possible()
just return
s without bc_do_exec()
ing已经积累的格式良好的命令(echo 10 11
在您的示例中)。然后在return
ing 之后,函数error()
退出xargs
程序。
我原本预计会有 12 到 15 人出现在其中之一中。
因为如果输入项本身太长,saidxargs
总是退出,所以后面的所有项都会丢失。
tl;博士
仅在以下情况-x
下才有意义-n <argumentCount>
:<argumentCount>
参数(如果可用)必须适合单个命令行,基于隐式最大字节数或明确指定的-s <byteCount+1>
选项;如果不是,则xargs
退出并出现错误。
如果没有-x
,将构造一个具有较少参数的命令行,并且不会发生错误 - 除非甚至没有一个参数适合 - 请参阅下一点。
-x
逻辑隐式适用于-L <lineCount>
and-I <placeHolder>
选项。-x
似乎-n
在 BSD 实现中被破坏了-见下文。xargs
没有-n
,就没有理由使用-x
,因为两种xargs
实现在遇到单个参数时总是以错误退出,这会导致整个字节大小限制的命令过长(同样,无论是隐含的还是用 指定的)。-s <byteCount+1>
xargs
: -x
没有-n
表面上的错误(从 v4.2.2 开始),正如Armali's hepful answer中所发现的那样。xargs
: -x
without-n
在语法上不受支持。-x
,一个太长的参数也会导致错误:
$ echo 1 10 | xargs -s 7 echo # max. command length is 6 (7 - 1) bytes
1 # ok: 'echo 1' is 6 bytes
xargs: argument line too long # 'echo 10' is too long
以下GNU xargs
示例:
-x
)或必须使用(带 -x
)每个命令实例:-n 2
-s 9
注意:对于BSD xargs
,下面的no -x
示例的工作方式相同,并且该-x
示例应该可以工作,但不适xargs
用于 OSX 10.11.3 和 PC-BSD 10.1 上的版本:只要-x
指定,指定的<argumentCount>
值 in-n <argumentCount>
将被忽略并xargs
表现好像-n 1
已经指定了一样。
# NO -x: Use 2 arguments *if possible*.
$ echo -e "1 2 3 4a 5 6" | xargs -n 2 -s 9 echo
1 2
3 # 'echo 3 4a' is more than 8 (9 - 1) bytes -> '3' is used *alone*
4a # 'echo 4a 5' also doesn't fit -> '4a' is also used alone.
5 6
# WITH -x: *Must* use 2 arguments (if available); *fail* otherwise.
$ echo -e "1 2 3 4a 5 6" | xargs -n 2 -s 9 -x echo
xargs: argument list too long # 'echo 3 4a' is too long; cannot use 2 arguments -> error
1 2
请注意在最后一次成功执行的命令之前如何奇怪地打印错误消息;这可能与上述错误有关,因此Armali 的回答可能会提供解释。