后台子进程会随父进程一起死亡吗?

后台子进程会随父进程一起死亡吗?

我有一个脚本调用其他几个子脚本。它后来被杀死,这似乎杀死了所有的子脚本。

在大多数情况下,这就是我想要的。但有一两种情况我不想让孩子死。

我想我记得能够通过&调用脚本时使用 a 来阻止这种情况的发生。

谁能证实这一点吗?

答案1

这里有很多因素需要考虑。请接受这个答案轻微当我凭记忆写下所有这些细节时,我持怀疑态度。 (如果您发现任何错误,请通过编辑或评论纠正我。)

如果使用后台命令&,然后父 shell 正常退出,则后台命令将继续运行。

但是,如果您以交互方式运行,“后台”命令在尝试读取或写入终端时将被阻止。 (无论父 shell 是否仍在运行,这都适用。)如果 stdout、stdin 和 stderr 被重定向,则这无关紧要。

如果您将命令置于后台,然后您的 SSH 会话断开连接,则后台命令可能会终止。我相信这是因为您的 shell 会将 SIGHUP 发送到其所有子进程,但我不能 100% 确定其细节。

如果您在将某个作业设置为后台后否认该作业(使用内置的 bash disown),那么它不会仅仅因为您的 SSH 会话终止而终止。但是,尝试写入终端或从终端读取时被阻止的方面仍然适用(对于交互式会话)。

我所知道的最通用的方法是在后台启动子脚本或进程,这样无论生成它的 shell 发生什么情况(并且无论它是交互启动还是从脚本启动),它都不会受到影响,是:

nohup somecommand >/dev/null 2>&1 </dev/null &

这假设您不关心命令的任何输出到其标准输出或标准错误,并且不需要向其提供任何标准输入。

如果您很高兴子脚本继承其父级的文件描述符(即终端不是问题或者您有其他解决方案),那么您真正需要的应该是:

./some-sub-script &
exit

只是附带说明一下,如果您正在编写一个旨在保持运行的守护进程,(a) 使用日志并 (b) 干净地轮换日志。

相关内容