xargs 的示例-x 选项的作用

发布于 2024-09-05 13:01:53 字数 227 浏览 1 评论 0原文

GNU xargs 有选项“-x”。手册页说:

-x 如果超出大小(请参阅 -s 选项)则退出。

但是 xargs 似乎并不关心是否设置了 -x 。我无法举出一个 -x 具有任何效果的示例。

请提供两个示例,其中唯一的区别是添加了 -x 并产生不同的输出。

GNU xargs has option '-x'. The man page says:

-x Exit if the size (see the -s option) is exceeded.

But xargs seems to not care if -x is set or not. I have been unable to make an example in which the -x has any effect at all.

Please provide two examples in which the only difference is an added -x and that produce different output.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

平生欢 2024-09-12 13:01:53

你必须设置一个大小来测试你是否超过了它。

$ 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

You have to set a size to test whether you've exceeded it.

$ 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
风吹短裙飘 2024-09-12 13:01:53

我仍然无法解释为什么给出 1 - 11:

(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 回显

但这给出了 1 - 9:

(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 -x 回显

-x 是否总是只给出一行的差异(即太长的行)?

这当然取决于您使用的 xargs 类型,但流行的 GNU findutils 的 xargs (很可能就是您所拥有的)具有这种行为,违反了最小惊讶原则:它通过重复读取下一个输入项并将其附加到现有命令行,直到它不适合行长度,在内存中累积命令行......现在,它检查读取的项是否会“ t 甚至可以作为单个参数放入一行(示例中的 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);
}

这是选项 -x (对应于 bc_ctl.exit_if_size_exceeded)的位置区别 - 使用-xexec_if_possible()只是返回,而没有bc_do_exec()已经积累的好-形成的命令(在您的示例中为 echo 10 11)。然后,在return之后,函数error()退出xargs程序。

我本来预计其中一个会有 12 - 15 个。

因为如果输入项本身太长,则所述 xargs 总是 退出,因此所有后续项都会丢失。

I still cannot explain why this gives 1 - 11:

(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 echo

but this gives 1 - 9:

(seq 11; echo -e "1234111";seq 12 15) | xargs -s 11 -x echo

Will -x always only give a difference of one single line (namely the line that would have been too long)?

This depends of course on the kind of xargs you're using, but the prevalent GNU findutils' xargs (which may well be the one you have) has exactly this behavior, violating the principle of least astonishment: It accumulates a command line in memory by repeatedly reading the next input item and appending it to the existing command line until it doesn't fit in the line length… Now, it checks whether the read item wouldn't even fit in a line as a single argument (which is the case with echo 1234111 in your example):

      if (p >= endbuf)
        {
          exec_if_possible ();
          error (EXIT_FAILURE, 0, _("argument line too long"));
        }

(the above code is near the end of function read_line() in findutils-4.6.0/xargs/xargs.c, nearly same in 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);
}

Here's where option -x (corresponding to bc_ctl.exit_if_size_exceeded) makes a difference - with -x, exec_if_possible() just returns without bc_do_exec()ing the already accumulated well-formed command (echo 10 11 in your example). Then after returning, the function error() exits the xargs program.

I had sort of expected 12 - 15 to be in one of them.

Because said xargs always exits if an input item is too long by itself, all following items are lost.

我们只是彼此的过ke 2024-09-12 13:01:53

tl;dr

  • 使用 -x 仅与 -n 一起使用才有意义:< strong> 参数(如果可用)必须适合单个命令行,基于隐式字节计数最大值或显式指定-s 选项;如果不是,xargs 将退出并出现错误。
    如果没有-x,将构造一个更少参数的命令行,并且不会发生错误 - 除非甚至没有单个< /em> 参数适合 - 请参阅下一点。

    • 请注意,-x 逻辑隐式适用于-L-I< /code> 选项。

    • 警告:从 OSX 10.11.3 和 PC-BSD 10.1 开始,-x-n 的组合似乎是 < xargsBSD 实现中出现了问题 - 请参阅下文。

  • 如果没有 -n,就没有理由使用 -x,因为两个 xargs 实现总是当遇到单个参数时退出并返回错误,该参数将导致命令对于整体字节大小限制太长(同样,无论是隐含的还是用指定的) -s)。

    • GNU xargs-x 没有 -n 表面bug(从 v4.2.2 开始),如Armali 的有益回答中所述。
    • BSD xargs:不带 -n-x 语法上不支持 .
    • 简单的示例表明,对于两种实现,即使没有 -x,单个太长的参数也会导致错误:
      • <代码>$ echo 1 10 | xargs -s 7 echo # 最大。命令长度为 6 (7 - 1) 个字节
        1 # ok: 'echo 1' 是 6 个字节
        xargs: 参数行太长 # 'echo 10' 太长

以下 GNU xargs 示例:

  • 指定连续 2 个参数(如果可用)< em>应该使用,如果可能不使用-x)或必须使用 -x) 对于每个命令实例:-n 2
  • 将每个命令限制为不超过 8 (9 - 1) 个字节:-s 9

注意:对于 BSD xargsno -x 示例下面的工作原理相同,-x 示例应该工作,但不适用于 OSX 10.11.3 和 PC 上的 xargs 版本-BSD 10.1:每当指定 -x 时,-n 中指定的 值将被忽略,并且 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 的回答 可能会提供解释。

tl;dr

  • Use of -x only makes sense with -n <argumentCount>: <argumentCount> arguments, if available, must fit on a single command line, based on either the implicit byte-count maximum or an explicitly specified -s <byteCount+1> option; if not, xargs exits with an error.
    Without -x, a command line with fewer arguments would be constructed, and no error would occur - unless not even a single argument fits - see next point.

    • Note that -x logic implicitly applies to the -L <lineCount> and -I <placeHolder> options.
    • Caveat: As of OSX 10.11.3 and PC-BSD 10.1, the combination of -x and -n appears to be broken in the BSD implementation of xargs - see below.
  • Without -n, there is NO reason to use -x, because both xargs implementations always exit with an error when they encounter a single argument that would result in a too-long command for the overall byte-size limit (again, either implied or specified with -s <byteCount+1>).

    • GNU xargs: -x without -n surfaces a bug (as of v4.2.2), as unearthed in Armali's hepful answer.
    • BSD xargs: -x without -n is syntactically not supported.
    • Simple example that shows for both implementations that, even without -x, a single too-long argument causes an error:
      • $ 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

The following GNU xargs examples:

  • specify that a succession of 2 arguments, if available, should be used, if possible (without -x) or must be used (with -x) for each command instance: -n 2
  • limit each command to not more than 8 (9 - 1) bytes: -s 9

Note: With BSD xargs, the no -x example below works the same, and the -x example should work, but doesn't with the xargs version found on OSX 10.11.3 and PC-BSD 10.1: whenever -x is specified, the specified <argumentCount> value in -n <argumentCount> is ignored and xargs behaves as if -n 1 had been specified.

# 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

Note how the error message is curiously printed before the last successfully executed command; this is possibly connected to the bug mentioned above, so Armali's answer may offer an explanation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文