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

我怀疑使用后台操作符&符(&)运行脚本是否会可以做到这一点,因为我尝试过,后来发现该过程尚未完成。如何注销并保持进程运行?

#1 楼

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


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

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

两个流行的终端多路复用器是screen和tmux。

屏幕学习曲线陡峭。这里是一个很好的教程,其中包含说明概念的图表: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

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

评论


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

– Mark Booth
2011-09-15 10:33

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

– Mark Booth
2011-09-15 23:02

*咳嗽*咳嗽*咳嗽*

–疯狂
2011-09-16在0:07



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

–h0tw1r3
2011年9月16日15:31

@TheLQ-byobu是GNU屏幕。您仍在使用屏幕,仅使用高度自定义的.screenrc。

–EEAA
2011-09-16 21:34

#2 楼

有几种方法可以执行此操作,但是我发现最有用的一种方法是使用GNU屏幕。ssh进入后,运行screen。这将启动另一个在屏幕上运行的外壳程序。运行您的命令,然后执行Ctrl-a d。

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

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

评论


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

– olafure
2011年9月15日下午12:06

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

– doc_id
2011-09-15 17:11

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

–h0tw1r3
2011年9月16日15:31

+1为tmux。我在5周前放弃了屏幕。

–布莱恩·亨特(Bryan Hunt)
2012年6月6日在8:46

#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

评论


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

– doc_id
2011-09-15 17:34



是的-这是bash专用的,因为bash是我用过的唯一shell。我不知道其他shell是否支持类似的东西(即在没有nohup的情况下在后台启动)–如果有人可以为其他shell发布其他答案,那将是非常好的。

– Jeremy Visser
2011年9月16日下午2:46

看到我的回答显示如何使用任何sh-lookalike方法

– w00t
2011年9月16日下午16:49

+1是因为以后可以决定。就在这一刻,我需要这个。像广告一样工作

– code_monk
2014年11月2日,凌晨3:45

#4 楼

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

评论


到目前为止,这是最简单的答案。来自的任何输出都会自动定向到nohup.out,以后可以检查。

–朱利安
2011年9月15日上午10:01

nohup完全不需要zsh。

–亚伦·布朗
2011-09-15 11:55

nohup是正确的答案,它是没有挂断的简称。

– Kinjal Dixit
2011-09-15 19:18

nohup在比屏幕上更多的计算机上发现,因此您应该知道如何使用它。

–氙气
2011年9月15日在21:11

#5 楼

为了更全面,我将指出tmux,它的基本概念与屏幕相同:


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


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



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

评论


使用“ gnu屏幕”作为搜索查询效果很好。

–gnur
2011-09-15 7:45



tmux +1000!

–mbq
2011年9月15日在12:29

#6 楼

屏幕对于在退出时仅使进程保持运行状态具有过大的作用。 />屏幕,使程序可以在受控制终端保护的环境中执行。例如,在dtach控制下的程序
不会由于某些原因而断开终端的连接。

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

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

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


评论


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

–蓬松
2011-09-15 18:12

dtach链接已死。

–user45793
20/09/11'上午6:22

也许现在在github.com/crigler/dtach上?

–user45793
20年9月11日在6:29

#7 楼

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

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


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

因此,您需要做的就是关闭stdin并后台处理该工作。真的很不错,请先执行cd /,这样您就不必再挂载了。

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

评论


有趣。这出现了一些值得注意的问题。我可以看到您将STDIN设置为空,-运算符?
– doc_id
2011-09-16 22:29

当您执行x <&-时,将关闭文件描述符x。在这种情况下,没有x,这会使bash默认为1,即标准输入。如果使用
– w00t
2011-09-19 17:15

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

– w00t
2011年9月19日在17:19

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

– Jeremy Visser
2011-10-15 14:06



@JeremyVisser听起来真的很合理!

– w00t
2011-10-17 8:36

#8 楼

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

at now


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

可以选择带日期的时间或类似now的时间表达式来代替now + 15 minutes 。有关更多详细信息,请参见man at

#9 楼

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

nohup允许在背景,其输出路由到日志文件,如果不需要,可以始终将其重定向到/ dev / null。