# start a command
% sleep 5000 &
[1] 3820
# check it
% jobs
[1]+ Running sleep 5000 &
# disown everything
% disown -a
# check it again (gone from shell)
% jobs
%
# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml 3820 23791 0 00:16 pts/1 00:00:00 sleep 5000
%
2016年编辑:
此问答早于systemd v230 崩溃。从 systemd v230 开始,新的默认设置是终止终止登录会话的所有子项,无论采取了哪些历史上有效的预防措施来防止这种情况发生。可以通过设置来更改行为
KillUserProcesses=no
,/etc/systemd/logind.conf
或者使用 systemd 特定的机制在用户空间启动守护进程来规避行为。这些机制超出了这个问题的范围。下面的文字描述了事物在 UNIX 设计空间中的传统工作方式比 Linux 存在的时间更长。
他们会被杀死,但不一定立即被杀死。这取决于 SSH 守护进程需要多长时间才能确定您的连接已断开。下面是一个更长的解释,将帮助您理解它的实际工作原理。
当您登录时,SSH 守护进程为您分配一个伪终端并将其附加到您的用户配置的登录 shell。这称为控制终端。您在该点正常启动的每个程序,无论外壳有多深,最终都会将其祖先追溯到该外壳。
pstree
您可以使用命令观察这一点。当与您的连接关联的 SSH 守护进程确定您的连接已断开时,它会向
SIGHUP
登录 shell 发送一个挂断信号 ( )。这会通知 shell 您已经消失并且它应该开始自行清理。此时发生的事情是 shell 特定的(在其文档页面中搜索“HUP”),但在大多数情况下,它会SIGHUP
在终止之前开始发送到与其关联的正在运行的作业。反过来,这些进程中的每一个都会在收到该信号时执行它们被配置为执行的任何操作。通常这意味着终止。如果这些工作有自己的工作,信号通常也会被传递。在控制终端挂起后幸存下来的进程要么是那些与终端解除关联的进程(您在其中启动的守护进程),要么是使用前缀
nohup
命令调用的进程。(即“不要挂断”)守护进程以不同方式解释 HUP 信号;由于它们没有控制终端并且不会自动接收 HUP 信号,因此它被重新用作管理员的手动请求以重新加载配置。具有讽刺意味的是,这意味着大多数管理员直到很久很久以后才了解这个信号对非守护进程的“挂断”用法。这就是您阅读本文的原因!终端多路复用器是在断开连接之间保持 shell 环境完好无损的常用方法。它们允许您以一种稍后可以重新附加到它们的方式与您的 shell 进程分离,而不管这种断开是意外的还是故意的。
tmux
并且screen
是比较受欢迎的;使用它们的语法超出了您的问题范围,但值得研究。有人要求我详细说明 SSH 守护进程需要多长时间才能确定您的连接已断开。这是一种特定于 SSH 守护进程的每个实现的行为,但您可以指望它们在任何一方重置 TCP 连接时终止。如果服务器尝试写入套接字并且 TCP 数据包未被确认,那么这将很快发生,或者如果没有任何内容试图写入 PTY,则这将缓慢发生。
在这种特定情况下,最有可能触发写入的因素是:
SO_KEEPALIVE
)。Keepalive 相当于服务器或客户端不经常向另一端发送数据包,即使没有其他原因有理由写入套接字。虽然这通常是为了避开使连接过快超时的防火墙,但它有一个额外的副作用,即导致发件人注意到另一方没有更快地响应。TCP 会话的通常规则适用于此:如果客户端和服务器之间的连接中断,但在问题期间双方均未尝试发送数据包,则连接将继续存在,前提是双方随后都做出响应并接收到预期的 TCP序号。
如果一方确定套接字已死,效果通常是立竿见影的:sshd 进程将发送
HUP
并自行终止(如前所述),或者客户端将检测到的问题通知用户。值得注意的是,仅仅因为一方认为另一方已经死亡并不意味着另一方已被告知这一点。连接的孤立端通常会保持打开状态,直到它尝试写入它并超时,或者从另一端接收到 TCP 重置。(如果当时连接可用)此答案中描述的清理仅在服务器注意到后才会发生。正如其他人所提到的,一旦您与 ssh 断开连接,其中运行的任何内容都将消失。
正如@Michael Hampton和其他人所提到的,您可以使用诸如
tmux
或之类的工具screen
来断开/重新连接到终端而不会丢失其内容(即子进程)。此外,您可以使用与号将进程置于后台
&
,然后使用该命令disown
将它们与当前 shell 解除关联。不,任何仍然附加在终端上的程序,并且没有像 之类的东西放在后台
nohup
,都会被杀死。这就是为什么有虚拟终端解决方案,如
tmux
和更早screen
的创建会话,即使您断开连接也能继续运行,并且您可以稍后重新连接。