when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.
为什么 ssh 断开后运行的命令会退出呢?
明确元凶:
SIGHUP 信号
简单的来说:
因为所有进程都得有个父进程。当 ssh 到一个服务器上时,打开的 shell 就是所有执行命令的父进程,当断开 ssh 连接后,在 ssh 中运行命令的父进程就没了。如果处理不当,这些进程就会收到 SIGTERM 信号,全被干掉了
详细的原因:
在 Linux/Unix 中,有这样几个概念:
进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组 ID,即进程组长进程的 ID
会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期 ID 为首进程的 ID
会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组,其余进程组称为后台进程组。
根据 POSIX.1 定义:
挂断信号(SIGHUP)默认的动作是终止程序
当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)
如果会话期首进程终止,则该信号发送到该会话期前台进程组
一个进程退出导致一个孤儿进程组产生时,如果任意一个孤儿进程组进程处于 STOP 状态,发送 SIGHUP 和 SIGCONT 信号到该进程组中所有进程
因此当网络断开或终端窗口关闭后,也就是 ssh 断开后,控制进程收到 SIGHUP 信号退出,会导致该会话期内其他进程退出
解决方法:
要么让进程忽略 SIGHUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程
nohup
1 | $ nohup ping baidu.com & |
setsid
1 | $ setsid ping baidu.com & |
()
1 | $ (ping baidu.com &) |
disown
1 | $ ping baidu.com |
使用 screen 这一类辅助程序
either I will find a way, or I will make one.