断开连接后保持远程 SSH 会话和进程运行的 5 种方法
简单来说, SSH或安全 Shell是一种可以远程访问其他系统上其他用户的方式,但只能在命令行(即非 GUI 模式)中访问。用更专业的术语来说,当我们通过 ssh 登录到其他系统上的其他用户并在该机器上运行命令时,它实际上会创建一个伪终端并将其附加到已登录用户的登录 shell 上。
当我们退出会话或者会话空闲一段时间后超时的时候,会向伪终端发送SIGHUP信号,并且所有在该终端上运行的作业,甚至其父作业是在伪终端上启动的作业,也会发送SIGHUP信号并被强制终止。
不要错过: 保持 SSH 服务器安全和受保护的 5 个有用做法
只有配置为忽略此信号的作业才会在会话终止后继续存在。在 Linux 系统上,我们可以通过多种方式让这些作业在用户注销和会话终止后仍在远程服务器或任何机器上运行。
了解 Linux 上的进程
正常流程
正常进程是指那些具有会话生命周期的进程。它们在会话期间作为前台进程启动,并在特定时间跨度或会话注销时结束。这些进程的所有者是系统的任何有效用户,包括 root。
孤儿进程
孤儿进程是指最初有父进程创建该进程,但一段时间后,父进程意外死亡或崩溃,使得 init 成为该进程的父进程。此类进程的直接父进程是 init,它会等待这些进程,直到它们死亡或结束。
守护进程
这些是一些故意孤立的进程,这些故意留在系统上运行的进程被称为守护进程或故意孤立的进程。它们通常是长期运行的进程,一旦启动,就会与任何控制终端分离,以便它们可以在后台运行,直到它们无法完成或最终抛出错误。此类进程的父进程故意死亡,使子进程在后台执行。
断开连接后保持 SSH 会话运行的技术
有多种方法可以在断开连接后保持 ssh 会话继续运行,如下所述:
1. 使用 screen 命令保持 SSH 会话运行
screen是 Linux 的一个文本窗口管理器,它允许用户同时管理多个终端会话,在会话之间切换,记录屏幕上正在运行的会话的会话,甚至在任何我们需要的时间恢复会话,而不必担心会话被注销或终端被关闭。
可以启动 screen 会话,然后将其从控制终端分离,让它们在后台运行,然后可以随时甚至在任何地方恢复。您只需在 screen 上启动会话,然后在需要时将其从伪终端(或控制终端)分离并注销。当您觉得可以时,您可以重新登录并恢复会话。
启动屏幕会话
输入“screen”命令后,您将进入一个新的 screen 会话,在此会话中,您可以创建新窗口、在窗口之间移动、锁定屏幕,以及执行在普通终端上可以执行的更多操作。
$ screen
一旦屏幕会话启动,您可以运行任何命令并通过分离会话来保持会话运行。
拆卸屏幕
当您想退出远程会话,但又想保持在该机器上创建的会话处于活动状态时,您只需将屏幕与终端分离,使其不再有控制终端。完成此操作后,您就可以安全地注销。
要从远程终端分离屏幕,只需“Ctrl+a”
立即按下 ,然后按“d”
,您将返回到终端,看到屏幕已分离的消息。现在您可以安全注销,并且您的会话将保持活动状态。
恢复分离的 Screen 会话
如果您想恢复注销前离开的独立屏幕会话,只需重新登录到远程终端并输入,“screen -r”
如果只打开了一个屏幕,则输入,如果打开了多个屏幕会话,则运行“screen -r <pid.tty.host>”
。
$ screen -r $ screen -r <pid.tty.host>
要了解有关 screen 命令的更多信息以及如何使用它,请点击链接:使用 screen 命令管理 Linux 终端会话
2. 使用 Tmux(终端多路复用器)保持 SSH 会话运行
Tmux是另一款旨在替代screen的软件。它具有screen的大部分功能,并增加了一些比 screen 更强大的附加功能。
除了屏幕提供的所有选项之外,它还允许在多个窗口之间水平或垂直分割窗格、调整窗格大小、会话活动监视、使用命令行模式编写脚本等。由于 tmux 的这些特性,它已被几乎所有 Unix 发行版广泛采用,甚至已被包含在 OpenBSD 的基本系统中。
启动 Tmux 会话
在远程主机上执行 ssh 并输入tmux后,您将进入一个新会话,并在您面前打开一个新窗口,您可以在其中执行在普通终端上执行的任何操作。
$ tmux
在终端上执行操作后,您可以将该会话与控制终端分离,以便它进入后台并且您可以安全地注销。
从终端分离 Tmux 会话
您可以“tmux detach”
在运行 tmux 会话时运行,也可以使用快捷方式(Ctrl+b then d)
。此后,您的当前会话将被分离,您将返回到终端,然后可以安全地注销。
$ tmux detach
恢复已关闭的 Tmux 会话
要重新打开您在退出系统时分离并离开的会话,只需重新登录到远程计算机并键入“tmux connect”即可重新连接到已关闭的会话,它将仍然在那里并运行。
$ tmux attach
要了解有关 tmux 的更多信息以及如何使用它,请点击链接:使用 Tmux 终端多路复用器管理多个 Linux 终端。
3. 使用 nohup 命令保持 SSH 会话运行
如果你对screen或tmux不太熟悉,可以使用nohup并将长时间运行的命令发送到后台,这样你就可以继续,而命令将继续在后台执行。之后,你可以安全地注销。
使用 nohup 命令,我们告诉进程忽略ssh 会话终止时发送的SIGHUP信号,从而使命令即使在会话注销后仍会继续存在。会话注销后,命令将从控制终端分离,并继续作为守护进程在后台运行。
在后台使用 nohup 执行命令
这里有一个简单的场景,我们运行find 命令,使用 nohup 在 ssh 会话的后台搜索文件,之后该任务被发送到后台,并立即返回提示,给出进程的PID和作业ID([JOBID] PID)
。
# nohup find / -type f $gt; files_in_system.out 2>1 &
恢复会话以查看作业是否仍在运行
当您再次重新登录时,您可以检查命令的状态,将其带回前台以'fg %JOBID'
监视其进度等。下面的输出显示该作业已完成,因为它在重新登录时没有显示,并给出了显示的输出。
# fg %JOBID
4. 使用 disown 命令保持 SSH 会话运行
让您的命令或单个任务在后台运行并且在会话注销或断开连接后仍然保持活动的另一种优雅方法是使用disown。
Disown,从系统的进程作业列表中删除该作业,这样该进程就不会在会话断开时被杀死,因为在您注销时它不会收到来自 shell 的SIGHUP 。
这种方法的缺点是,它只应用于不需要任何来自stdin的输入并且也不需要写入stdout 的作业,除非您特意重定向作业的输入和输出,因为当作业尝试与stdin或stdout交互时,它将会停止。
在后台使用 disown 执行命令
下面,我们将ping命令发送到后台,以便 ut 继续运行并从作业列表中删除。如图所示,该作业首先被暂停,之后它仍然在作业列表中,进程 ID:15368。
$ ping example.com > pingout & $ jobs -l $ disown -h %1 $ ps -ef | grep ping
在该 disown 信号传递给作业之后,作业将从作业列表中删除,但仍在后台运行。当您重新登录远程服务器时,作业仍会运行,如下所示。
$ ps -ef | grep ping
5. 使用 setsid 命令启动 SSH 会话
另一个实现所需行为的实用程序是setsid。Nohup有一个缺点,即进程的进程组保持不变,因此使用 nohup 运行的进程容易受到发送给整个进程组的任何信号的影响(如)Ctrl + C
。
另一方面,setsid为正在执行的进程分配一个新的进程组,因此,创建的进程完全位于新分配的进程组中,并且可以安全执行,而不必担心即使在会话注销后被终止。
使用 setsid 执行任何命令
这里表明,‘sleep 10m’
自从进程创建以来,它已经与控制终端分离。
$ setsid sleep 10m $ ps -ef | grep sleep
现在,当您重新登录会话时,您仍然会发现该进程正在运行。
$ ps -ef | grep [s]leep
结论
您能想到哪些方法,即使在退出 SSH 会话后也能保持进程运行?如果您能想到任何其他有效的方法,请在评论中提及。