将进程添加到已经执行的进程中?就像&&或者这样

将进程添加到已经执行的进程中?就像&&或者这样

这个问题启发了我另一个相关问题。想象一下你开始

% nohup a.sh &

然后要在完成b.sh时执行(例如,将处理的输出。和都是长时间运行的过程,需要数小时才能完成。)a.shb.sha.sha.shb.sh

基本上你想模拟

% nohup a.sh && b.sh

b.sh但你启动时忘记添加了a.sh。这能实现吗?最好是在 zsh 中。

答案1

如果启动该进程的 shell 仍然知道它(尝试jobs),那么内置的 shellwait可以等待它完成。像这样的事情可能会起作用:

$ jobs
[1] nohup a.sh
$ wait -f %1 && nohup b.sh &

如果您在 shell 中丢失了关联,则该pidwait命令可能会以类似的方式工作,尽管它可能无法捕获第一个进程的退出值,并且即使第一个进程失败也可能运行第二个进程,这与所做的不同&&

答案2

只有父进程(或子子收割机,如果有或init父进程死亡)可以检索进程的退出状态。

从启动命令的 shell 中,您可以等待它,如果成功,则b.sh在后台启动:a.sh

wait $pid && nohup b.sh &

在 zsh 中或:

wait -f "$pid" && { nohup b.sh & }

在最新版本的 bash 中(当进程仅停止时,-ffor不返回;这是 中的默认行为)。waitzsh

但是wait必须在前台运行。如果在后台运行,它将位于子 shell 进程中,因此将不再是正在运行的进程的父进程nohup a.sh

要检索不是您的子进程的退出状态,一种方法是使用调试器并拦截_exit()exit_group()等效的系统调用。

例如,在 Linux 上,可以这样做:

ret=$(strace -qqqa0 -e signal=none -e exit_group -p "$pid" 2>&1 | grep -Po '\(\K\d+')

macos 的等效项可能涉及trussordtrace命令,但我没有机器来测试它。

相关内容