如果我在SSH连接断开之前运行一个命令,命令是否继续执行?
在大多数情况下,没有。 进程将在terminal丢失时发送SIGHUP。 你可以用'nohup'作为前缀来忽略信号。 看到:
我会在线程中添加另一个暗示的build议,这是我刚刚在几分钟之前学到的:
如果你已经开始了一个需要很长时间的进程(在我的情况下tar恢复),忘记在它前面包含nohup,你仍然可以防止它在注销时终止。
这里是步骤:
一般来说,虽然不知道你在运行什么shell甚至是什么操作系统,但是很难说。 例如,如果你在屏幕下运行它,我认为行为是分离并继续运行。 也许有些其他的shell有可configuration的选项。
正如华纳上面所说的,ssh守护进程(即loginshell和subprocess)的孩子将会得到SIGHUP ,但是他们不会立即得到它们。 将有一个延迟,有时在服务器端的SSH守护程序放弃您的连接之前几分钟。 在此期间,这个过程将继续运行。
正如华纳所说,进程可以select忽略SIGHUP ,在这种情况下,它将继续运行,直到它需要input,然后发现STDIN已经closures。
华纳的答案是现货。 或者,也可以在后台执行该命令,在该命令的末尾添加“&”(&)。
我在下面的链接find了最好的答案
从SSH会话中断开连接是否会中止程序?
编辑2016年:
这个问答早于systemd v230的崩溃。 从systemd v230开始,新的默认设置是终止终止login会话的所有子节点,而不pipe采取什么历史上有效的预防措施来防止这种情况发生。 可以通过在/etc/systemd/logind.conf中设置KillUserProcesses = no来改变行为,或者在用户空间中使用systemd特有的机制来启动一个守护进程。 这些机制不在这个问题的范围之内。
下面的文本描述了UNIXdevise空间中传统的工作方式比Linux存在的时间更长。
他们会被杀死,但不一定立即。 这取决于SSH守护进程需要多长时间才能确定您的连接已经死亡。 接下来的是一个更长的解释,将帮助你理解它是如何工作的。
login后,SSH守护程序会为您分配一个伪terminal,并将其附加到您的用户configuration的loginshell。 这被称为控制terminal。 每一个在这个阶段正常启动的程序,无论多深层次的shell,最终都会“追溯其祖先”回到shell。 你可以用pstree命令来观察这个。
当与您的连接关联的SSH守护程序进程确定您的连接已经死亡时,它会向loginshell发送一个挂断信号(SIGHUP)。 这通知你已经消失的shell,它应该开始清理自己; 在这一点上发生了什么是特定于shell的(search其“HUP”的文档页面),但是大多数情况下,它将在终止之前开始发送SIGHUP以运行与其关联的作业。 反过来,每个进程都将完成他们在接收到该信号时所做的任何configuration。 通常这意味着终止。 如果这些工作有自己的工作,信号也往往会传递。
在控制terminal挂起的过程中,这些过程是从terminal(你开始的守护进程)或者用前缀nohup命令调用的terminal。 (即“不要挂在这个”)
terminal多路复用器是在断开连接之间保持shell环境完整的常用方式。 它们允许你脱离你的shell进程,以便以后可以重新连接到它们,不pipe这个断开是偶然的还是故意的。 tmux和screen是比较stream行的。 使用它们的语法超出了你的问题的范围,但它们值得深入研究。
有人要求我详细说明“SSH守护程序需要多长时间才能确定您的连接已经死亡”。 这是特定于SSH守护进程的每个实现的行为,但您可以指望所有这些行为在任一方重置TCP连接时终止。 如果任一方尝试写入套接字并且TCP数据包未被确认,则这将快速发生,或者如果双方都不试图写入PTY,则会发生缓慢。
在这个特定的背景下,最有可能触发写作的因素是:
A process (typically the one in the foreground) attempting to write to the PTY on the server side. (server->client) The user attempting to write to the PTY on the client side. (client->server) Keepalives of any sort. These are usually not enabled by default, either by the client or the server, and there are typically two flavors: application level and TCP based (ie SO_KEEPALIVE). Keepalives amount to either the server or the client infrequently sending packets to the other side, even when nothing would otherwise have a reason to write to the socket. While this is typically intended to skirt firewalls that time out connections too quickly, it has the added side effect of causing the sender to notice when the other side isn't responding that much more quickly.
TCP会话的通常规则适用于此处:如果客户端和服务器之间的连接中断,但双方都不会在问题发生期间尝试发送数据包,则只要双方都事后响应,并且接收到预期的TCP序列号。
如果一方已经确定套接字已经死了,那么效果通常是即时的:sshd进程将发送HUP并自行终止(如前所述),否则客户端会通知用户检测到的问题。 值得注意的是,仅仅因为一方认为另一方已经死亡并不意味着另一方已经被告知这一点,并且通常会保持开放,直到它试图写入连接或者从另一方接收到TCP重置。 (如果连接可用的话)