注销后保持Linux进程运行

doc*_*_id 145 linux ssh bash process

我正在通过 SSH 连接到一台 Linux 机器,并且我正在尝试运行一个重型 bash 脚本来进行文件系统操作。预计它会持续运行数小时,但由于互联网连接问题,我无法让 SSH 会话保持打开状态。

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

les*_*ana 136

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


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

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

两个流行的终端多路复用器是screentmux

Screen有一个陡峭的学习曲线。这是一个很好的教程,其中包含解释该概念的图表:http : //www.ibm.com/developerworks/aix/library/au-gnu_screen/


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

两种简单的方法是nohupdisown

有关如何nohupdisown工作的更多信息,请阅读此问题和答案:https : //unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

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

  • 我喜欢这个答案,因为它为交互式和非交互式情况提供了解决方案。在交互式情况下,`screen` 给了你更多的选择,但是如果你使用 `authorized_keys` 来允许人们通过 `ssh` 远程运行脚本,`nohup` 选项是一个很好的简单的脚本方式启动持续时间比用于启动它们的`ssh` 会话更长的进程。 (3认同)
  • \*咳嗽\*tmuxis更好\*咳嗽\* (3认同)
  • [tmux](http://tmux.sourceforge.net/) > 屏幕。试试吧,你永远不会回去。 (3认同)

EEA*_*EAA 94

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

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

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

当您想重新连接到 screen 会话时,只需screen -RD从 shell 提示符运行(作为创建会话的同一用户)。

  • Screen 有一大堆命令,都是以 Ctrl-a 开头的。如果你只学了一个额外的,从“Ctrl-a ?”开始。那么你就不会学习“Ctrl-a c”和“Ctrl-a n” (6认同)

Jer*_*ser 76

在 中bashdisown关键字非常适合于此。首先,在后台运行您的进程(使用&,或者^Z输入bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156
Run Code Online (Sandbox Code Playgroud)

通过键入jobs您可以看到该进程仍由 shell 拥有:

$ jobs
[1]+  Running  wget
Run Code Online (Sandbox Code Playgroud)

如果您此时注销,后台任务也会被终止。但是,如果您运行disownbash 会分离作业并允许它继续运行:

$ disown
Run Code Online (Sandbox Code Playgroud)

您可以确认这一点:

$ jobs
$ logout
Run Code Online (Sandbox Code Playgroud)

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

$ wget --quiet http://server/some_big_file.zip & disown
$ logout
Run Code Online (Sandbox Code Playgroud)

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

  • +1 因为可以稍后决定。就在这一刻,我需要这个。像宣传的那样工作 (2认同)

Kor*_*van 37

大多数 Linux 机器上可用的工具 nohup 可以做到这一点。

  • nohup 根本不需要 zsh。 (3认同)
  • 这是迄今为止最简单的答案。任何输出都会自动定向到 nohup.out 并可以稍后检查。 (2认同)
  • nohup 在比屏幕多得多的机器上找到,所以你应该知道如何使用它。 (2认同)

Han*_*an5 27

为了彻底,我将指出tmux,它与 screen 具有相同的基本思想:

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

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

然而,在谷歌上搜索几乎无限容易。

  • +1000 为 tmux! (4认同)
  • 使用 `"gnu screen"` 作为你的搜索查询效果很好。 (2认同)

小智 13

Screen 只是在您注销时保持进程运行是过度的。

尝试dtach

dtach 是一个用 C 编写的程序,它模拟屏幕的分离特性,它允许程序在不受控制终端保护的环境中执行。例如,dtach 控制下的程序不会受到终端因某种原因断开连接的影响。

dtach 是因为 screen 不能充分满足我的需求而编写的;我不需要 screen 的额外功能,例如支持多终端或终端仿真支持。屏幕也太大,笨重,并且有难以理解的源代码。

screen 还干扰了我使用全屏应用程序,如 emacs 和 ircII,因为它过度解释了程序和附加终端之间的流。dtach 没有终端仿真层,将程序的原始输出流传递给附加的终端。dtach 执行的唯一输入处理是扫描分离字符(指示 dtach 与程序分离)和处理挂起键(它告诉 dtach 在不影响正在运行的程序的情况下暂时挂起自身),这两者都可以如果需要,可以禁用。

与屏幕相反,dtach 具有最少的功能,而且非常小。这使 dtach 可以更轻松地审计错误和安全漏洞,并使其可在空间有限的环境中访问,例如在救援磁盘上。


w00*_*00t 9

这是一种守护任何 shell 进程的方法,不需要外部程序:

( while sleep 5; do date; done ) <&- >output.txt &
Run Code Online (Sandbox Code Playgroud)

当您关闭会话时,该作业将继续运行,正如 output.txt 文件所证明的那样(该文件具有缓冲功能,因此需要一段时间才能显示非零值)。不要忘记在测试后终止你的工作。

所以你需要做的就是关闭标准输入和后台工作。要想真正做到最好,首先cd /不要紧抓着坐骑。

这甚至适用于 Solaris 下的简单 sh。

  • 我认为原因是当父进程关闭其子进程的 stdin 句柄时会触发 SIGHUP(导致子进程在 shell 死亡时退出的实际信号)。但是,如果 stdin *开始 * 为空,而不是事后关闭,则父级无法触发 SIGHUP。不错的发现,虽然 - 从来没有想到过。 (2认同)

小智 7

byobu在 Ubuntu 上是一个不错的屏幕前端。通过按Ctrl-?您可以获得所有键盘快捷键的列表。它添加了一个状态栏,可用于查看 CPU 负载、磁盘空间等。总的来说,它提供了一种体验,我将其描述为基于终端的 VNC 连接。

nohup 允许在后台启动作业,并将其输出路由到日志文件,如果不需要,它始终可以重定向到 /dev/null。


rjm*_*nro 7

at命令对于这种情况很有用。例如,键入:

at now
Run Code Online (Sandbox Code Playgroud)

然后您可以输入将要运行的一个命令或一系列命令。如果在机器上正确设置了电子邮件,结果应该通过电子邮件发送给您。

now您可以选择使用日期或时间表达式(如 )来指定时间,而不是now + 15 minutes。有关man at更多详细信息,请参阅。