在 SSH 会话断开连接后保持进程运行

λ J*_*kas 262 command-line ssh background-process

有时我想在回家之前启动一个长时间运行的进程,所以我创建了一个到服务器的 SSH 会话来启动这个进程,但是我想关闭我的笔记本电脑回家,晚饭后,我想检查我在下班前开始的过程。我怎样才能用 SSH 做到这一点?我的理解是,如果您中断 SSH 连接,您也会中断服务器上的登录会话,从而终止长时间运行的进程。

War*_*ung 282

使用nohup让您的过程中忽略挂起信号:

$ nohup long-running-process &
$ exit
Run Code Online (Sandbox Code Playgroud)

  • 它们具有相似的目的,但在许多方面有所不同。`nohup` 拦截 SIGHUP,这样当运行它的 shell 退出并向所有仍在运行的子进程发送 SIGHUP 时,`long-running-process` 不会死。`disown` 只是从 Bash 的子列表中删除指定的作业,因此它根本不会尝试发送 SIGHUP。`nohup` 是一个独立于 shell 的程序,所以它适用于所有 shell,而 `disown` 是一个 Bash 内置程序。`nohup` 接受要运行的命令,而 `disown` 仅在作业启动并且您已将其设置为后台后才起作用,以便您可以返回 shell。 (39认同)
  • 就是这个。无需安装 screen 或 tmux。这实际上是一种很好的旧方法。当然,'screen' 或 'tmux' 都是很棒的应用程序,应该在需要时使用,但就像在后台运行一个可以注销的进程一样简单,请执行上述操作。 (31认同)
  • `tail -f nohup.out` 来检查你回来时发生了什么。 (21认同)
  • nohup 像 disown 吗? (3认同)
  • 对于那些不熟悉 nohup 和 disown 的人来说很棒的快速回顾 - 以及一些处理终端会话的简单方法 http://www.serverwatch.com/tutorials/article.php/3935306/Detach-Processes-With-Disown-和-Nohup.htm (3认同)
  • 这对我来说根本行不通。我使用 nohup 运行该进程,注销,3 秒后重新登录。进程已经死了。 (2认同)
  • @Andrew:它会立即[将 `long-running-process` 置于后台](https://bash.cyberciti.biz/guide/Putting_jobs_in_background),因此您无需通过单独的步骤即可注销。 (2认同)

San*_*ndy 167

您想使用 GNU Screen。超级棒!

ssh me@myserver.com
screen               #start a screen session
run-a-long-process
Run Code Online (Sandbox Code Playgroud)

CTRL+ a,d脱离你的屏幕会话

exit                 #disconnect from the server, while run-a-long-process continues
Run Code Online (Sandbox Code Playgroud)

当你回到你的笔记本电脑时:

ssh me@myserver.com
screen -r            #resume the screen session
Run Code Online (Sandbox Code Playgroud)

然后检查您长期运行的流程的进度!

screen是一个非常全面的工具,可以做的比我描述的要多得多。在屏幕会话中,尝试 ctrl+a,? 学习一些常用命令。可能最常见的是:

  • CTRL+ a,c创建一个新窗口
  • CTRL+ a,n切换到屏幕会话中的下一个窗口
  • CTRL+ a,p切换到屏幕会话中的上一个窗口
  • 如果您从一堆不同的系统登录,您可能会不小心将自己连接到另一台计算机上的活动屏幕会话。出于这个原因,我总是恢复screen -d -r以确保如果另一个 shell 附加到我的屏幕会话,它会在我在当前系统上恢复之前被分离。

  • tmux 是屏幕的现代模拟。 (10认同)
  • `tmux` 和 `tmuxinator` 是精美设置的绝佳组合,而我更喜欢将 `screen` 作为快速而简单的解决方案。 (3认同)
  • 如果您出于某种原因想要共享终端,屏幕非常酷。创建一个屏幕 `screen -S name` 并让你的其他朋友使用 `screen -x name` 连接到它。 (2认同)

Mik*_*ton 57

如果您没有提前计划和设置screen等,请执行以下操作:

  1. 如果您的进程在后台运行:转到 #3,否则:Ctrl-Z暂停前台进程。这将报告挂起进程的作业编号,例如:

    [1]+  Stopped                 processName
    
    Run Code Online (Sandbox Code Playgroud)
  2. 发送processName到后台bg %1(使用任何作业 # 跟随%)。这将processName在后台恢复。

  3. 断绝 processNamedisown %1disown PID-h如果您想在终止当前 shell 之前保持所有权,请使用该标志。

  • 谢谢你!我有一份工作正在运行,但我认为我无法让它继续下去,因为我在开始它时没有使用 `&`。这似乎很好用! (5认同)
  • 这真太了不起了!我从来不知道 Linux 可以让你像这样转移对活动进程的控制。我担心在长时间运行的过程中通过 SSH 连接到我的服务器时我的电池会耗尽,这就是我的答案! (5认同)

txw*_*ger 17

您想要使用的是 screen 或者更好的用户友好的 screen 包装器,称为 byobu。

Screen 允许您在同一个 ssh 会话中运行多个虚拟终端会话。提供教程帮助页面

byobu是一个包装器,它允许使用简单的功能键而不是 ctrl-a 的组合键轻松打开新屏幕。它还显示了一个状态行,其中包含所有可以命名的打开的虚拟终端。

另一个不错的功能是,当您的 ssh 连接断开时,您的所有屏幕都可以保持正常运行。您只需通过 ssh 再次连接并调用 byobu,一切都和以前一样。

最后是byobu的一些截图


cja*_*jac 12

可能值得注意的是

ssh -t lala screen -rxU moo将附加到主持人lala上的moo会话

ssh -t lala screen -S moo将在主机lala上创建moo会话

ssh -t lala screen -S moo quux将在主机lala上创建moo会话并运行程序quux,完成后退出会话。


nns*_*nse 9

老问题,奇怪的是仍然没有人建议tmux,它充当 n 个控制台的包装器,并在需要时保持打开状态。除了 tmux 具有的许多功能之外,这允许更多的控制。管理它很容易,你只需执行 tmux,它会带你进入它的外壳,开始你的 looong 工作,然后按 ctrl+b 后跟 d(分离)(ctrl+b是 tmux 的“ok google”,d是关闭的命令无需退出外壳)。如果你只是关闭,例如,腻子,这实际上有效。晚餐后,当您再次连接时,您可以重新打开 tmux withtmux attach以查看您离开时的屏幕。我喜欢的东西是拆分窗格:ctrl+b然后按"。要从一个窗格更改为另一个窗格,ctrl+b然后按向上/向下箭头。


kal*_*iko 9

2021 年,我们还建议 Linux 发行版使用 systemdsystemd-run作为分离进程并在关闭 ssh 登录后保持其运行的方式。

人们可以启动一个command,给它一些名称,例如“ background_cmd_service ”,然后将其转变为一项 systemd 服务。稍后检查状态:

systemd-run --unit=background_cmd_service --remain-after-exit command
# later on
journalctl -b -u background_cmd_service.service
systemctl status background_cmd_service.service

Run Code Online (Sandbox Code Playgroud)

当以普通用户身份启动服务时,可能需要启用延迟(参见enable-lingerloginctl 选项)。即使使用 nohup 也是如此,因为一旦用户注销,systemd 就会清理会话中运行的所有服务。

对于脚本或其他可执行文件,您可以提供可执行文件的路径,如下所示:

systemd-run --unit=background_cmd_service --remain-after-exit --working-directory=/full/path/ command
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下标准选项停止服务或清除失败的服务systemctl

systemctl stop background_cmd_service.service

systemctl reset-failed background_cmd_service.service

许多 2016 年之前但在堆栈交换上获得高度投票的答案表明 nohupdisowncommand &(command &) 自 2016 年以来不再工作,因为 systemd 在用户注销后处理用户进程的方式发生了默认更改 -详细信息


Vic*_* A. 8

您可以在此处找到一个很好的指南: 断开连接时保持 SSH 会话运行

sudo apt-get install screen
Run Code Online (Sandbox Code Playgroud)

现在,您只需在命令行中键入 screen 即可开始新的 screen 会话。您将看到有关屏幕的一些信息。按回车键,您将进入正常提示。

要断开连接(但让会话保持运行),请立即依次 点击Ctrl+ACtrl+ D。你会看到消息[分离]

重新连接到已经运行的会话

screen -r
Run Code Online (Sandbox Code Playgroud)

重新连接到现有会话,或者如果不存在则创建一个新会话

screen -D -r
Run Code Online (Sandbox Code Playgroud)

在正在运行的屏幕会话中创建一个新窗口 Hit Ctrl+A然后C立即连续。您将看到一个新提示。

从一个屏幕窗口切换到另一个 Hit Ctrl+A然后Ctrl+A立即连续。

列出打开的屏幕窗口 Hit Ctrl+A然后W立即连续


小智 6

Tmux是一个不错的选择,可用于在后台运行长时间运行的进程。

我必须在谷歌云平台的 VM 实例/服务器(操作系统:Ubuntu 16.0)上继续运行长时间运行的进程。在我必须从终端启动 SSH 终端的地方,我必须保持终端连接以运行该过程。现在到此为止,一切都很好。但是请等待,如果与我的 SSH 终端的连接终止,那么长时间运行的进程会立即停止,因此一旦 ssh 终端重新启动或从新的 ssh 终端重新启动,我必须再次重新运行它们。

我发现这tmux是一个很好的解决方案,可以避免在终端关闭后终止我们想要运行的进程。

终端多路复用器( tmux) 启动tmux会话:

  1. 启动ssh终端
  2. 键入tmux。它将在同一个终端中打开一个窗口。
  3. 运行命令以在 tmux 会话中启动长时间运行的进程。

现在,即使 SSH 终端突然关闭/终止,tmux 会话也会继续在实例/服务器上运行已启动的 lon 运行进程。

如果连接终止,那么如何重新连接它以查看后台 tmux 会话中运行的进程:

  1. 重新连接或打开新的 ssh 终端。要查看此进程(在后台保持运行),请键入:tmux attach命令。

想要终止 tmux 会话:

  1. 停止进程。然后输入exittmux-terminal-window。

(注意:如果我们使用tmux detach命令:它将退出 tmux 会话窗口/终端而不终止/停止 tmux 会话)

更多详情请参考以下文章:

  1. https://www.tecmint.com/keep-remote-ssh-sessions-running-after-disconnection/
  2. https://limitlessdatascience.wordpress.com/2019/08/22/tmux-to-keep-jupyter-notebook-running-in-the-background/


Rob*_*its 5

我使用 NX NoMachine,它对我来说是免费的,因为它只有我一个人使用。本质上,它在服务器上运行一个 X 会话,您可以反复连接和断开连接。当您未连接时,X 会话会继续运行。可以从任何地方建立连接。您可以选择浮动窗口或包含整个桌面的单个窗口(例如完整的 Gnome 桌面)。客户端(您将在笔记本电脑上运行)可以在 Linux、MacOS、Solaris 或 Microsoft Windows 上运行。在后一种情况下,如果您选择浮动窗口,它们将单独显示在 Windows 任务栏上。

我使用我的 Windows XP 笔记本电脑(我拥有的某些特定于 Windows 的硬件需要它)作为我的两台使用 NX Nomachine 的 Linux 服务器的前端。我什至可以从 Linux 打印到连接到我的 Windows 笔记本电脑的打印机。