Shell xargs'的示例-行动中的x选项

Shell 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

GNU
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”太长

以下GNU
xargs
示例:

  • 指定每个命令实例应使用连续的两个参数(如果可用),如果可能(没有
    -x
    )或必须使用(有
    -x
    ):
    -n2
  • 将每个命令限制为不超过8(9-1)字节:
    -s9

注意:对于BSD
xargs
,下面的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
是没有意义的,因为GNU
xargs
在遇到单个参数时总是带着错误退出,这将导致命令过长,无法达到隐含或指定的字节大小限制。因此,在您的示例中,
#error and continue
具有误导性,因为该命令将不会继续:try
echo-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);
}