如何让 `xargs` 忽略孩子的退出并继续进一步处理

Chr*_*urm 25 kill signals xargs

我有时会在xargs一夜之间运行很长时间的工作,并且在早上发现xargs中间某个地方死了真的很烦人,例如因为在一个特殊情况下的分段错误,就像今晚发生的那样。

即使一个xargs孩子被杀死,它也不会处理任何更多的输入:

控制台 1:

[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>
Run Code Online (Sandbox Code Playgroud)

控制台 2:

[09:35:54] kill 5601
Run Code Online (Sandbox Code Playgroud)

xargs一旦子进程终止并继续处理,我能否以某种方式阻止停止处理更多输入?

ckh*_*han 25

不,你不能。来自xargssavannah.gnu.org来源

if (WEXITSTATUS (status) == CHILD_EXIT_PLEASE_STOP_IMMEDIATELY)
  error (XARGS_EXIT_CLIENT_EXIT_255, 0,
         _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]);
if (WIFSTOPPED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status));
if (WIFSIGNALED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: terminated by signal %d"), bc_state.cmd_argv[0], WTERMSIG (status));
if (WEXITSTATUS (status) != 0)
  child_error = XARGS_EXIT_CLIENT_EXIT_NONZERO;
Run Code Online (Sandbox Code Playgroud)

该检查或调用它的函数周围没有标志。它似乎确实与 max procs 相关,我认为这是有道理的:如果您将 max procs 设置得足够高,则在达到限制之前它不会打扰检查,而您可能永远不会这样做。

对于您正在尝试做的事情,一个更好的解决方案可能是使用GNU Make

TARGETS=$(patsubst %,target-%,$(shell seq 1 40))

all: $(TARGETS)

target-%:
    sleep 10; date +"%H:%M:%S $*"
Run Code Online (Sandbox Code Playgroud)

然后:

$ make -k -j4 
Run Code Online (Sandbox Code Playgroud)

将具有相同的效果,并为您提供更好的控制。


小智 11

似乎最明显的口语之一只被其他提案提及。

也就是说,您可以使用以下内容:

bash -c '$PROG_WHICH_MAY_FAIL ; (true)'
Run Code Online (Sandbox Code Playgroud)

为了“强制成功”。

请注意,这与lornix的提议一致(只是没有那么多话)。

无论如何,由于这实际上忽略了实际的流程退出状态,我会确保您考虑以某种方式保存子流程状态以进行事后分析。例如:

bash -c '$PROG_WHICH_MAY_FAIL || touch failed; (true)'
Run Code Online (Sandbox Code Playgroud)

true这里是有些多余,因此这可能是更好的写法如下:

bash -c '$PROG_WHICH_MAY_FAIL || touch failed'
Run Code Online (Sandbox Code Playgroud)

因为我们可能想知道何时无法触及“失败”文件。换句话说,我们不再忽视失败,我们正在注意并继续。

并且,在考虑了这个问题的递归性质之后,也许我们确切地看到了为什么xargs 不会让忽略失败变得容易。因为这从来都不是一个好主意 - 您应该在正在开发的过程中增强错误处理。然而,我相信这个概念在“Unix 哲学”本身中更为固有。

最后,我想这也是 James Youngman 通过推荐所暗示的trap,大概可以以类似的方式使用。也就是说,不要忽视这个问题......抓住它并处理它,否则你有一天醒来发现没有一个子程序成功;-)