退出后保持 Linux 进程运行

退出后保持 Linux 进程运行

我通过 SSH 连接到 Linux 机器,并尝试运行一个执行文件系统操作的大型 bash 脚本。该脚本预计会运行数小时,但由于网络连接问题,我无法让 SSH 会话保持打开状态。

我怀疑使用后台运算符(&符号 ( &))运行脚本是否可行,因为我试过,后来发现该过程未完成。我该如何注销并保持进程运行?

答案1

最好的方法是在终端多路复用器中启动进程。或者,您可以让进程不接收 HUP 信号。


A终端复用器提供独立于“真实”终端运行的“虚拟”终端(实际上,当今的所有终端都是“虚拟”的,但这是另一天的主题)。即使您的真实终端已通过 ssh 会话关闭,虚拟终端仍将继续运行。

从虚拟终端启动的所有进程将继续与该虚拟终端一起运行。当您重新连接到服务器时,您可以重新连接到虚拟终端,除了时间流逝之外,一切都会像什么都没发生一样。

两种流行的终端多路复用器是屏幕tmux

Screen 的学习难度很高。下面有一个很好的教程,其中有图表解释了该概念:http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


高血压当终端关闭时,终端会向其所有子进程发送信号(或 SIGHUP)。收到 SIGHUP 后的常见操作是终止。因此,当您的 ssh 会话断开连接时,您的所有进程都将终止。为了避免这种情况,您可以让您的进程不接收 SIGHUP。

两种简单的方法是nohupdisown

有关其工作原理的更多信息,nohupdisown阅读以下问题和答案:https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

注意:虽然进程将继续运行,但您无法再与它们交互,因为它们不再连接到任何终端。此方法主要用于长时间运行的批处理进程,一旦启动,就不再需要任何用户输入。

答案2

有几种方法可以做到这一点,但我发现最有用的方法是使用GNU 屏幕

ssh 登录后,运行screen。这将启动在屏幕内运行的另一个 shell。运行您的命令,然后执行Ctrl- a d

这将“断开”您与屏幕会话的连接。此时,您可以注销或做任何其他您想做的事情。

当您想要重新连接到屏幕会话时,只需screen -RD从 shell 提示符运行(以创建会话的相同使用用户身份)。

答案3

bash里面disown关键字非常适合此目的。首先,在后台运行您的进程(使用&,或者^Z然后输入bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

通过输入jobs你可以看到该进程仍然归 shell 所有:

$ jobs
[1]+  Running  wget

如果你此时注销,后台任务也会被终止。但是,如果你运行disown,bash 分离该作业并允许其继续运行:

$ disown

您可以确认这一点:

$ jobs
$ logout

您甚至可以将&和组合disown在同一行,例如:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

在我看来,这比运行更好,nohup因为它不会让nohup.out文件散落在文件系统中。此外,nohup必须在运行命令之前运行 -disown如果您稍后才决定要后台运行并分离任务,则可以使用它。

答案4

为了全面,我要指出tmux,其基本思想与 screen 相同:

tmux 旨在成为 GNU screen 等程序的现代、BSD 许可替代品。主要功能包括:

  • 强大、一致、有据可查且易于编写脚本的命令界面。
  • 窗口可以水平或垂直分割成多个窗格。
  • 窗格可以自由移动和调整大小,或排列成预设的布局。
  • 支持 UTF-8 和 256 色终端。
  • 使用多个缓冲区进行复制和粘贴。
  • 用于选择窗口、会话或客户端的交互式菜单。
  • 通过在目标中搜索文本来更改当前窗口。
  • 终端锁定,手动或超时后。
  • 一个干净、易于扩展、BSD 许可的代码库,正在积极开发中。

然而,在 Google 上搜索几乎要容易得多。

相关内容