注销后保持linux进程运行


142

我正在通过SSH连接到Linux计算机,并且试图运行繁重的bash脚本来进行文件系统操作。预计它将持续运行几个小时,但由于存在互联网连接问题,我无法将SSH会话保持打开状态。

我怀疑使用背景运算符&符(&)运行脚本是否可以解决问题,因为我尝试了一下,后来发现该过程尚未完成。如何注销并保持进程运行?

Answers:


135

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


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

从虚拟终端启动的所有进程将继续与该虚拟终端一起运行。当您重新连接到服务器时,您可以重新连接到虚拟终端,并且除了经过的时间之外,其他一切似乎都没有发生。

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

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


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

两种简单的方法是nohupdisown

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

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


3
我喜欢这个答案,因为它为交互式和非交互式情况提供了解决方案。在交互式情况下,screen为您提供了更多选择,但是,如果您正在使用authorized_keys允许人们通过远程运行脚本ssh,则该nohup选项是脚本启动进程的一种简单方法,其持续时间比ssh用于启动它们的会话更长。
Mark Booth,

1
@rahmanisback-请记住,您可以随时更改接受的答案。仅仅因为到目前为止EricA的答案被最高评价并不意味着它对您来说是最好的答案,确实使它成为您接受的答案很可能会鼓励更多的人将其投票为一个好的答案。
Mark Booth

3
*咳嗽*咳嗽*咳嗽*
crasic 2011年

3
tmux >屏幕。尝试一下,您将永不退缩。
h0tw1r3 2011年

1
@TheLQ-byobu GNU屏幕。您仍在使用屏幕,只是带有高度自定义的.screenrc。
EEAA 2011年

92

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

ssh进入后,运行screen。这将启动另一个在屏幕上运行的外壳程序。运行您的命令,然后执行Ctrl- a d

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

当您想重新连接到屏幕会话时,只需screen -RD在shell提示符下运行即可(与创建会话的用户相同)。


6
屏幕上有一堆命令,全部以Ctrl-a开头。如果您仅学习其他一项,请从“ Ctrl-a?”开始。然后,您将不会学习“ Ctrl-a c”和“ Ctrl-a n”
olafure 2011年

@olafure +1,谢谢。屏幕似乎将成为我的主要工具箱。
doc_id 2011年

tmux >屏幕。尝试一下,您将永不退缩。
h0tw1r3 2011年

+1为tmux。5周前,我放弃了屏幕。
布莱恩·亨特

73

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

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

通过键入jobs您可以看到该进程仍归外壳所有:

$ 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如果仅在以后决定要后台和分离任务,则可以使用此命令。


1
1+是一个很好的答案。nohup或Screen的唯一偏好是bash的独立性,并且可能与其他shell一起使用。但是,无论何时我使用bash,我都会坚持使用您的方法。
doc_id 2011年

是的-这是bash专用的,因为bash是我使用过的唯一外壳。我想知道其他shell是否支持任何类似的功能(即在没有nohup的情况下在后台启动)–如果有人可以为其他shell发布其他答案,那将是很棒的。
杰里米·维瑟

1
看到我的答案显示了如何使用任何类似sh的方法
w00t

1
+1是因为以后可以决定。就在这一刻,我有这个需要。如广告所示工作
code_monk


27

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

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

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

但是,在Google上搜索几乎无限地容易。


2
使用"gnu screen"您的搜索查询工作得很好。
gnur 2011年

4
tmux +1000!
mb11年

11

屏幕过于简单,仅在注销时保持进程运行。

尝试dtach

dtach是用C编写的程序,它模仿屏幕的分离功能,该程序允许在不受控制终端保护的环境中执行该程序。例如,在dtach控制下的程序不会由于某些原因而断开终端的连接。

之所以写dtach是因为屏幕无法充分满足我的需求;我不需要屏幕的其他功能,例如支持多个终端或终端仿真支持。屏幕也太大,笨重,并且源代码很难理解。

屏幕也干扰了我对全屏应用程序(例如emacs和ircII)的使用,因为它过多地解释了程序与连接的终端之间的流。dtach没有终端仿真层,并将程序的原始输出流传递到连接的终端。dtach唯一执行的输入处理是扫描分离字符(这表明dtach从程序中分离)并处理暂停键(告诉dtach暂时暂停其自身而不影响正在运行的程序),这两者都可以如果需要,请禁用。

与屏幕相反,dtach具有最少的功能,并且非常小。这使dtach可以更容易地进行审计,以检查是否有错误和安全漏洞,并使其在空间有限的环境(例如急救盘)中可以访问。


谢谢。我也是来这里发表有关dtach的。现在这是终端拆卸的必备条件;屏幕太多了,并且在很大程度上干扰了输入。事实上,屏幕需要自己的termcap令人不安。
蓬松的

9

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

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

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

因此,您需要做的就是关闭stdin并完成工作。首先,要真正成为一个好人,cd /请不要紧握坐骑。

即使在Solaris下的简单sh中也可以使用。


有趣。这出现了一些值得注意的问题。我可以看到您将STDIN设置为空,-操作员?< /dev/null和之间有什么区别&-?我想可以为STDIN(以及其他STDOUT和STDERR)分配一个文件< file,或者<& stream在STDIN的情况下分配一个流。< /dev/null在上面的示例中使用的方法是否相同?-上面的运算符是否将null称为流?
doc_id 2011年

当您执行x <&-时,将关闭文件描述符x。在这种情况下,没有x,这会使bash默认为1,即标准输入。如果使用</ dev / null,则不会关闭stdin,只是给程序提供一个空文件作为输入。
w00t

1
老实说,我真的不知道为什么它会守护您正在运行的内容:-)尽管它确实起作用,但我们在生产中使用了它。我在弄乱它的同时发现了它,希望我可以在shell中守护进程而无需任何特殊操作-因此我从关闭stdin开始,就足够了。我应该去阅读一些shell资料,但是我想如果您关闭stdin并后台运行该进程,它也会分离该进程。
w00t

2
我认为原因是当父进程关闭其子进程的stdin句柄时触发了SIGHUP(当shell死后,导致子进程退出的实际信号)。但是,如果stdin 开始为null,而不是事后被关闭,则父级将无法触发SIGHUP。不错的发现-永远不会想到这一点。
杰里米·维瑟

@JeremyVisser听起来真的很合理!
w00t

7

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

at now

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

相反的now,你可以用一个日期或时间表达喜欢选择指定的时间now + 15 minutes。请参阅man at以获取更多详细信息。


7

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.