Shell xargs'的示例-行动中的x选项
GNUShell xargs'的示例-行动中的x选项,shell,xargs,Shell,Xargs,GNUxargs具有选项'-x'。手册页上说: -如果超出大小(请参阅-s选项),则退出x 但是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
xargs
具有选项'-x'。手册页上说:
-如果超出大小(请参阅-s选项),则退出x
但是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就是这种情况):
(上述代码位于findutils-4.6.0/xargs/xargs.c中函数read_line()
的末尾,与findutils-4.4.2中的几乎相同)
这里是选项-x
(对应于bc\u ctl.exit\u如果超过了-x
,exec\u如果可能的话()
just返回s而不bc\u do\u exec()
调用已经积累的格式良好的命令(echo 10 11
)。然后在return
ing之后,函数error()
退出xargs
程序
我有点期待12-15在其中一个
因为如果一个输入项本身太长,所说的xargs总是存在,所以下面的所有项都会丢失。tl;dr
- 使用
-x
仅对-n有意义
- BSD
xargs
:-x
不带-n
在语法上不受支持
- 一个简单的示例显示,对于两种实现,即使没有
-x
,单个过长的参数也会导致错误:
$echo 1 10 | xargs-s 7 echo#最大命令长度为6(7-1)字节
1#好:'echo 1'是6个字节
xargs:参数行太长#“echo 10”太长
以下GNUxargs
示例:
- 指定每个命令实例应使用连续的两个参数(如果可用),如果可能(没有
-x
)或必须使用(有-x
):-n2
- 将每个命令限制为不超过8(9-1)字节:
-s9
注意:对于BSDxargs
,下面的no-x
示例的工作原理是相同的,-x
示例应该可以工作,但与OSX 10.11.3和PC-BSD 10.1上的xargs
版本不一样:只要指定了-x
,指定的就可以提供解释。您的示例说明了区别。Howe无论如何,我仍然无法解释为什么这会给出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
始终只给出一行的差异(即可能太长的行)?我有点期待其中的12-15个。使用-x
只对-n
有意义。如果没有-n
,-x
是没有意义的,因为GNUxargs
在遇到单个参数时总是带着错误退出,这将导致命令过长,无法达到隐含或指定的字节大小限制。因此,在您的示例中,#error and continue
具有误导性,因为该命令将不会继续:tryecho-e“12\n1234\n13”| xargs-s 8 echo
-13
不会被打印。使用-x
之前的参数也不会被处理(从v4.2.2开始),正如@Armali的回答中所解释的,很可能是一个bug。@mklement0:我同意“继续”是不正确的。它实际上处理了所有出现在导致错误的参数之前的有效参数,而该参数是致命的。我认为对于-s
,可能存在一些罕见的用例,您希望在其中出现这种行为,但我想不出具体的示例。请注意,对于-n
,仍然可能出现致命错误ode>-s
和-n
组合使用。虽然在您的示例中显示xargs-s 8-x echo
不处理任何参数,但实际上是这样的:只需在另外两个参数前面加上前缀,您就会看到它们被处理:echo-e“0\n1\n12\n1234”| xargs-s 8-x echo
。如上所述,添加-x
,也会在有问题的命令之前抑制-valid-命令,这听起来像是一个bug。在这种情况下使用-x
不仅不必要,而且实际上会引入不必要的行为(由于bug)是的,xargs
,无论选项如何,只要一个参数不合适,就会出现一个错误。@mklement0:这很奇怪,肯定是一个错误。为了节省未来读者的时间:如果您使用-s
设置大小限制,xargs将始终为您强制执行它-不-x
需要。-x
仅在我需要时才需要。-x
如果您还想强制每次调用使用指定数量的参数(-n没有说明这一点,并且还错误地暗示,-x
如果任何参数违反大小约束(对eff的错误解释),则根本不会处理任何参数
if (p >= endbuf)
{
exec_if_possible ();
error (EXIT_FAILURE, 0, _("argument line too long"));
}
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);
}