我有一个 bash 脚本 start.sh,它看起来像这样:
for thing in foo bar; do
{
background_processor $thing
cleanup_on_exit $thing
} &
done
这就是我想要的:我运行 start.sh,它以代码 0 退出,两个子 shell 在后台运行。每个子shell运行background_processor
,当它退出时,它运行cleanup_on_exit
。即使我退出最初运行 start.sh 的终端(即使那是 ssh 连接),这也有效。
然后我尝试了这个:
ssh user@host "start.sh"
这有效,除了start.sh
退出之后,ssh 显然还等待子shell 退出。我真的不明白为什么。退出start.sh
后,子shell 成为pid 1 的子shell,甚至没有为它们分配tty ......所以我不明白它们是如何与我的ssh 连接相关联的。
我后来试过这个:
ssh -t user@host "start.sh"
现在进程有一个分配的伪终端。现在,我发现 ssh 确实会在退出后立即start.sh
退出,但它也会杀死子进程。
我猜想在后一种情况下正在向子进程发送 SIGHUP,所以我这样做了:
ssh -t user@host "nohup start.sh"
这确实有效!所以,我有一个解决我的实际问题的方法,但我想在这里掌握 SIGHUP/tty 东西的微妙之处。
总之,我的问题是:
- 为什么 ssh(没有 -t)即使在
start.sh
退出后仍等待子进程,即使它们的父 pid 为 1? - 为什么 ssh (with -t) 会杀死子进程,显然是使用 SIGHUP,即使当我从终端运行它们并注销该终端时不会发生这种情况?