防止 xargs 在出错时退出

JDS*_*JDS 34 bash command-line-interface batch-processing xargs

根据手册页,如果执行行之一以 255 错误退出,则 xargs 将退出:

如果命令的任何调用以 255 的状态退出,xargs 将立即停止而不读取任何进一步的输入。发生这种情况时,会在 stderr 上发出错误消息。

我怎样才能让 xargs这样做?

我有一个大约 1500 行的批处理作业,我想一次运行 50 行。我发现它总是在某条生产线上死亡,并且没有完成工作。不好!

一个更好的问题,描述我正在尝试做的事情的问题是:

我怎样才能运行一个 1500 行的批处理脚本,一次 50 行,这样它就不会在中间退出作业,并将输出捕获到某种日志文件中?

小智 35

类似于larsksanswer 但更明确:

xargs sh -c "somecommand || true"
Run Code Online (Sandbox Code Playgroud)

  • 如果你想为每一行运行一个命令,你也需要`-i`。这应该有效:`xargs -i sh -c "somecommand {} || true"` (2认同)

小智 13

您可以使用另一个简单的 bash 脚本包装 perl 脚本:

#!/bin/bash
real-command "$@" || exit 0
Run Code Online (Sandbox Code Playgroud)

这将调用real-command将您传递给此fake-command 的所有参数传递给它,并且它将始终返回 0 退出代码(这意味着它始终成功)并且 xargs 永远不会因此而停止。


lar*_*sks 10

您可以编写 xargs 调用来屏蔽命令行的返回代码。使用类似以下内容,xargs将永远不会看到somecommand返回的退出代码:

xargs sh -c "somecommand || :"
Run Code Online (Sandbox Code Playgroud)


mat*_*fer 9

刚刚找到了一个有趣的答案,尽管它的用处取决于您尝试运行的命令。

如果您使用 xargs 基本上组装命令列表,您可以通过告诉 xargs 回显命令,然后管道到 bash 来获得此行为。

例如,如果您尝试删除可能存在或不存在的事物列表:

# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit

# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为首先,xargs 只调用 echo,所以它不会看到任何错误。其次,因为 bash 的默认行为是在语句失败后继续执行。

为了更具体地说明我的情况,我使用它从 AWS ElasticBeanstalk 中删除了一堆旧的应用程序版本,如下所示:

aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
  echo aws elasticbeanstalk delete-application-version \
       --delete-source-bundle --application-name myapp --version-label |\
bash
Run Code Online (Sandbox Code Playgroud)

  • 我会避免它,因为在您尝试使用 CTRL+C 取消之前,管道到 bash 看起来很优雅。我不得不为每个要处理的命令取消一次。有什么我不能在 xargs 级别而不是 bash 级别取消的吗? (2认同)

小智 5

以下施工对我有用:

ls | xargs -I % svn upgrade %
Run Code Online (Sandbox Code Playgroud)

即使 svn upgrade 在某些元素上失败,过程也会继续


Rog*_*ahl 5

如果您使用的是xargswith find,请使用-exec选项find

find . -name '*.log' -exec somecommand {} \;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢 - 我不知道 `xargs` 可以并行运行命令。凉爽的。如果您只想最大限度地减少命令调用次数,“-exec”有一个“+”参数。 (3认同)