我通过 SSH 连接到 Linux 机器,并尝试运行一个执行文件系统操作的大型 bash 脚本。该脚本预计会运行数小时,但由于网络连接问题,我无法让 SSH 会话保持打开状态。
我怀疑使用后台运算符(&符号 ( &
))运行脚本是否可行,因为我试过,后来发现该过程未完成。我该如何注销并保持进程运行?
答案1
最好的方法是在终端多路复用器中启动进程。或者,您可以让进程不接收 HUP 信号。
A终端复用器提供独立于“真实”终端运行的“虚拟”终端(实际上,当今的所有终端都是“虚拟”的,但这是另一天的主题)。即使您的真实终端已通过 ssh 会话关闭,虚拟终端仍将继续运行。
从虚拟终端启动的所有进程将继续与该虚拟终端一起运行。当您重新连接到服务器时,您可以重新连接到虚拟终端,除了时间流逝之外,一切都会像什么都没发生一样。
Screen 的学习难度很高。下面有一个很好的教程,其中有图表解释了该概念:http://www.ibm.com/developerworks/aix/library/au-gnu_screen/
这高血压当终端关闭时,终端会向其所有子进程发送信号(或 SIGHUP)。收到 SIGHUP 后的常见操作是终止。因此,当您的 ssh 会话断开连接时,您的所有进程都将终止。为了避免这种情况,您可以让您的进程不接收 SIGHUP。
有关其工作原理的更多信息,nohup
请disown
阅读以下问题和答案: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 上搜索几乎要容易得多。