题 我退出后保持linux进程运行


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

我怀疑使用后台运算符&符号运行脚本(&),会做的伎俩,因为我尝试了,后来发现这个过程没有完成。如何注销并保持进程运行?


139
2017-09-15 06:00






答案:


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


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

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

两个流行的终端多路复用器是 屏幕 和 TMUX

屏幕有一个陡峭的学习曲线。这是一个很好的教程,用图表解释了这个概念: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


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

有两种简单方法可以做到 nohup 和 disown

有关如何更多信息 nohup 和 disown 作品阅读这个问题和答案: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

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


132
2017-09-15 06:05



我喜欢这个答案,因为它为交互式和非交互式情况提供了解决方案。在互动案例中, screen 为您提供更多选择,但如果您正在使用 authorized_keys 允许人们通过远程运行脚本 ssh, nohup 选项是一个很好的简单方法,脚本可以启动持续时间超过的进程 ssh 用于启动它们的会话。 - Mark Booth
@rahmanisback - 请记住,您可以随时更改您接受的答案。只是因为到目前为止,EricA的答案得到最高的评价并不意味着它对你来说是最好的答案,确实让它成为你公认的答案可能会鼓励更多的人将其投票作为一个好答案。 - Mark Booth
*咳嗽* tmuxisbetter *咳嗽* - crasic
TMUX >屏幕。试试吧,你永远不会回去。 - h0tw1r3
@TheLQ - byobu 是 GNU屏幕。您仍在使用屏幕,只需使用高度自定义的.screenrc。 - EEAA


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

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

这将使您与屏幕会话“断开连接”。此时,您可以注销或执行您喜欢的任何其他操作。

如果要重新连接到屏幕会话,只需运行即可 screen -RD 从shell提示符(与创建会话的用户相同)。


92
2017-09-15 06:07



真棒!整洁的回答,谢谢...... - rahmanisback
屏幕有一大堆命令,全部以Ctrl-a开头。如果您只学习一个额外的,请从“Ctrl-a?”开始。那你就不会学习“Ctrl-a c”和“Ctrl-a n” - olafure
@olafure +1,谢谢。看起来Screen将成为我的主要工具箱。 - rahmanisback
TMUX >屏幕。试试吧,你永远不会回去。 - h0tw1r3
tmux为+1。我5周前放弃了屏幕。 - Bryan Hunt


bashdisown 关键字非常适合这种情况。首先,在后台运行您的流程(使用 &, 要么 ^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 如果您稍后决定要进行后台处理并分离任务,则可以使用它。


70
2017-09-15 12:27



这是一个非常好的答案,1 +。 nohup或Screen的唯一偏好是bash的独立性,可能与其他shell一起使用。但是每当我使用bash时,我都会坚持你的方法。 - rahmanisback
是的 - 这是特定于bash的,因为bash是我用过的唯一shell。我想知道其他炮弹是否支持任何相似的东西(即在没有nohup的背景下发射) - 如果有人可以发布其他炮弹的其他答案,那将是太棒了。 - Jeremy Visser
看看我的答案显示如何用任何sh-lookalike做到这一点 - w00t
+1因为能够稍后决定。就在这一刻,我需要这个。像宣传的那样工作 - code_monk


大多数Linux机器上都可以使用nohup工具。


37
2017-09-15 06:14



这是迄今为止最简单的答案。任何输出都会自动定向到nohup.out,稍后可以检查。 - Julian
nohup根本不需要zsh。 - Aaron Brown
nohup是正确答案,它没有挂断的简称。 - Kinjal Dixit
nohup可以在更多的机器上找到屏幕,所以你应该知道如何使用它。 - Zenon


为了彻底,我会指出 TMUX,它与屏幕具有相同的基本思想:

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

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

但是,在Google上搜索大约更容易。


27
2017-09-15 06:23



运用 "gnu screen" 因为您的搜索查询效果很好。 - gnur
tmux为+1000! - mbq


在您注销时只保持进程运行,屏幕过度。

尝试 dtach

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

dtach写的是因为屏幕没能充分满足我的需求;一世   不需要屏幕的额外功能,例如支持多个功能   终端或终端仿真支持。屏幕太大了,   笨重,并且源代码很难理解。

屏幕也干扰了我使用的全屏应用程序   emacs和ircII,由于它对流的过度解释   程序和附加的终端之间。 dtach没有   终端仿真层,并传递原始输出流   程序到附加的终端。唯一的输入处理   dtach确实执行扫描分离字符(发出信号   dtach脱离程序)并处理暂停密钥   (告诉dtach临时暂停而不影响   运行程序),如果需要,这两个都可以被禁用。

与屏幕相反,dtach具有最小的功能,并且非常小。   这使得dtach可以更容易地检查错误和安全性   孔,并使其可以在空间有限的环境中访问,   例如在救援盘上。


11
2017-09-15 15:06



谢谢。我来这里只是为了发布关于dtach的信息。现在终端分离是我的首选;屏幕确实太过分了,干扰输入到了荒谬的程度。事实屏幕需要它自己的termcap是非常令人不安的。 - fluffy


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

( while sleep 5; do date; done ) <&- >output.txt &

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

所以你需要做的就是关闭stdin并完成工作。真的很好,首先 cd / 所以你不要坚持坐骑。

这在Solaris下简单易用。


9
2017-09-16 16:48



有趣。这出现了一些值得注意的问题。我可以看到你将STDIN设置为空, - 运营商?有什么区别 < /dev/null 和 &- ?我想STDIN(和其他STDOUT和STDERR)可以分配一个文件 < file或者是一个流 <& stream 如果是STDIN。是否会使用相同的 < /dev/null 在你上面的例子?还有运营商吗? - 上面引用null作为流? - rahmanisback
当你执行x <& - 时,它会关闭文件描述符x。在这种情况下,没有x,这使得bash默认为1,即标准输入。如果您使用</ dev / null,那么您不是关闭stdin,而只是将一个空文件作为输入提供给程序。 - w00t
说实话,我真的不知道为什么这个守护你正在运行的东西:-)它确实有效,我们在生产中使用它。我发现它时一直在乱搞希望我可以在shell中守护进程而不需要任何特殊的东西 - 所以我开始关闭stdin,这就足够了。我应该阅读一些shell源代码,但我认为如果你关闭stdin并将进程置于后台,它也会分离进程。 - w00t
我认为原因是当父进程关闭其子进程的stdin句柄时,会触发一个SIGHUP(当shell死亡时导致子进程退出的实际信号)。但是,如果是stdin 开始了 为null,而不是在事后关闭,父母无法触发SIGHUP。不错的发现 - 从来没有想到过。 - Jeremy Visser
@JeremyVisser听起来真的很合理! - w00t


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

at now

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

代替 now,您可以指定时间,可选择使用日期或时间表达式 now + 15 minutes。看到 man at 更多细节。


7
2017-09-16 08:23





byobu 在Ubuntu上是一个很好的屏幕前端。按下 Ctrl键 -  您将获得所有键盘快捷键的列表。它添加了一个状态栏,可用于观察CPU负载,磁盘空间等。总体而言,它提供了一种体验,我将其描述为基于终端的VNC连接。

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


7
2017-09-15 13:26