结束ssh会话后如何保持进程运行?


Answers:


750

您应该寻找像这样的现代替代品tmux

tmuxscreen由于许多原因而优于,这只是一些示例:

  • Windows可以在会话之间移动,甚至可以链接到多个会话
  • Windows可以水平和垂直拆分为窗格
  • 支持UTF-8和256色端子
  • 可以从外壳控制会话,而无需输入会话

基本功能

要获得与答案推荐中所述相同的功能screen,您需要执行以下操作:

  • SSH到远程机器
  • 首先tmux输入tmux外壳
  • 在启动的tmux会话中开始您想要的过程
  • tmux通过输入Ctrl+ 离开/分离会话b,然后d

现在,您可以安全地从远程计算机注销,您的进程将继续在内部运行tmux。当您再次回来并想要检查流程状态时,可以使用它tmux attach来附加到tmux会话。

如果要让多个会话并排运行,则应使用Ctrl+ b和来命名每个会话$。您可以使用来获取当前正在运行的会话的列表tmux list-sessions,现在可以使用command附加到正在运行的会话tmux attach-session -t 0

tmux与在单个会话中处理单个窗口相比,可以执行更多高级的操作。欲了解更多信息,有一看man tmux还是在TMUX页面GitHub的。特别是,这是有关screen和之间主要区别的常见问题解答tmux


4
@CraigM使用screen -x -r [screenname]screen -rx简称,如果您仅激活一个屏幕会话。这使您可以附加现有的屏幕实例。
Lekensteyn 2012年

5
这个建议帮助我解决了同样的问题,但我认为它包含一个错字。我很确定您需要先键入Ctrl-b然后d离开/分离tmux会话。当然,tmux我的Ubuntu 12.04上的版本就是这种情况。
cxrodgers 2012年

17
按照上述说明操作时我犯了一个错误。如果有人可能会遇到相同的错误,我将分享它:我在自己计算机的外壳而不是远程计算机的外壳中启动tmux。需要在远程计算机的外壳中启动tmux。
Mert Nuhoglu 2014年

5
现在正在重新开发屏幕:lists.gnu.org/archive/html/screen-devel/2014-04/msg00024.html您能否更新答案?
muru 2014年

4
或者,运行tmux detach而不是打字ctrl-b d
安德鲁

305

选项1: nohup

最好的方法通常是最简单的。

nohup long-running-command &

它是专门为此设计的,甚至将stdout记录到nohup.log

man nohup

选项2: bg

如果您想“后台”一些已经运行的任务,那么最好的选择是Ctrl+ Z然后运行

bg

将您最近暂停的任务置于后台,使其继续运行。

然后,快速disown退出后即可保持该过程运行。

screen其他人可以做到,但这不是他们的目的。nohup对于那些您将要离开bg的任务,以及那些已经在运行并且不想重新启动的任务,我建议您这样做。

请记住,两者都是针对bash的。如果您不使用bash,则命令可能会有所不同。


4
我建议您这样做disown -h
米歇尔(Michele)

有趣的是,屏幕和tmux对矿工不起作用,bur nohup起作用
YasinOkumuş17年

1
bg+ disown对我不起作用。我有一个正在运行的部署脚本,我忘了在tmux内部开始,需要提前离开开会。脚本连续将进度输出到外壳。ctrl+z停止了该过程,使我重返bash。bg恢复了该过程,但也恢复了将状态输出为bash的状态,从而无法看到我在输入什么。然而,一条disown命令产生了“不存在:当前:没有这样的工作”
BrianHVB

julia myFile.jl无论出于什么原因,这都不适合我。tmux确实而且很棒。
kilgoretrout

这对我有用,非常感谢
Chad

207

您可以使用来做到这一点screen

键入man screen以查找更多信息或阅读此屏幕手册页

简单方案:

  • ssh到您的远程框中。键入screen然后启动所需的过程。

  • Ctrl- A然后Ctrl- D。这将“分离”您的屏幕会话,但使您的进程保持运行状态。您现在可以注销远程框。

  • 如果您想稍后再回来,请再次登录并键入“ screen -r这将“恢复”您的屏幕会话,您可以看到该过程的输出。


32
我通常会使用命名屏幕会话screen -S name,以便以后更轻松地连接到正确的屏幕会话。
大卫·奥尼尔

链接已
断开

1
就个人而言,我正在使用没有任何包装控制软件的盒子。从源头上花了大约半小时为TMUX(我个人有过类似经验)建立依赖关系之后,很明显,屏幕对我来说是更好,更简单的解决方案。TL; DR:针对此问题的最佳解决方案取决于用例,机器以及必须设置的时间。感谢您的答复:)
Max von Hippel

结合screen -S假前和screen -r回来时是惊人的!
Meloman '18

谢谢你 这个解决方案对我有用,而tmux却不起作用(我在将ssh插入Linux机器时使用Windows版本的bash)
Michael Sorensen

83

屏幕和nohup是更好的方法,但是如果必须分离一个已经在没有屏幕或nohup的情况下运行的进程,则可以运行disown命令。

disown [-ar] [-h] [jobspec… |pid… ]

如果没有选项,从活动作业表中删除每个作业规范。如果指定了该-h选项,则不会从表中删除作业,而是对其进行标记,以便如果Shell收到SIGHUP,则不会将SIGHUP发送到该作业。如果不存在jobspec,并且没有提供no-a-r选项,则使用当前作业。如果未提供jobspec,则该-a选项意味着删除或标记所有作业;-r没有jobspec参数的选项将操作限制为正在运行的作业。

使用disown,您可以关闭终端并在计算机上运行该进程。


10
这也是我最喜欢的方法。我经常使用disown -a && exit
Stefano Palazzo

1
完善。这是一个可爱的命令,值得所有赞扬!
格雷格

8
提醒一下,我使用Ctrl-Z停止了一个正在运行的进程,并且在调用前没有在后台启动它disown并杀死了它。
HDave 2014年

3
如果要写入终端,可能会崩溃。重定向正在运行的进程的输出并不那么容易。最好使用nohup正确启动它。
jiggunjer

2
这是一个很好的答案,因为它直接回答了问题。问题的作者询问了已经执行了许多长时间运行的命令该怎么做。这些答案大多数使您知道执行命令之前要做什么。
q0rban

53

我被困在一个大型MV中,因此无法停止该过程,设置屏幕并重新启动。通过基本上执行以下步骤,我设法退出了ssh会话并运行了进程:

  1. ssh [服务器]
  2. 命令
  3. Ctrl+Z
  4. bg
  5. 取消显示[process pid可选,默认为last]
  6. 出口

步骤3暂停当前进程(例如,我的“ mv”命令)。
步骤4将暂停的进程置于后台,然后继续执行。
步骤5让您放弃该过程。**要获得作业列表,只需jobs在之前键入。


**关于放弃(来自bash手册):

disown [-ar] [-h] [jobspec ... | pid ... ]
              Without  options,  remove  each jobspec from the table of active
              jobs.  If jobspec is not present, and neither the -a nor the  -r
              option  is  supplied, the current job is used.  If the -h option
              is given, each jobspec is not removed from  the  table,  but  is
              marked  so  that  SIGHUP  is  not  sent  to the job if the shell
              receives a SIGHUP.  If no jobspec is  supplied,  the  -a  option
              means  to  remove or mark all jobs; the -r option without a job‐
              spec argument restricts operation to running jobs.   The  return
              value is 0 unless a jobspec does not specify a valid job.

2
内置始终是我的首选:) THX
ken_oy

该答案应标记为正确。安装并习惯于使用屏幕来解决此问题被夸大了。
Ulrich-LorenzSchlüter,

当您已经启动任何命令并且运行了很长时间时,这将非常有用。终止,并在TMUX会话启动还需要时间
Deepali米塔尔

1
@ tom-brossman:请当心像这样的不必要的编辑!如果在没有作业指定的情况下调用disown内置命令,则该命令将对最新的后台作业起作用。
大卫·佛斯特

22

您可以使用两个主要程序来维护多个ssh连接上的程序和终端状态。它们是屏幕(现有的,但不幸的是未维护。显然现在正在积极开发)和tmux(较新的,正在积极维护)。Byobu是可以在这些系统之上运行的前端,并提供其他ubuntu状态信息。在新安装的设备上,它将使用tmux作为后端,如果您安装的是byobu较旧的设备,并且具有现有配置,它将保留先前的后端,无论是屏幕还是tmux。

o

可以在基于Debian的计算机上将Byobu安装在计算机上:

sudo aptitude install byobu

使用yum,您可以

su -c 'yum install byobu'

也可以在其他发行版上安装byobu。

使用byobu

byobu使用ssh连接后,可以通过在主机上运行来启动byobu 。这将为您提供一个如下所示的外壳:

意象

您还可以在具有-X选项的Ubuntu机器上使用Byobu Terminal,并轻松拥有完美运行的byobu。

用法:

通过键入开始byobu byobu

您可以按F2在当前会话中创建一个新窗口,按F3-F4在各个窗口之间切换。

关于byobu最好的部分是,您不必杀死终端中正在运行的进程即可离开终端。您只需将屏幕/ tmux(byobu的骨架)发送到背景,然后在下次访问时恢复:

  • 要使BYOBU保持运行(分离),请按F6。
  • 下次您来的时候,就去做byobu,您应该回到原来的位置。

    byobu-attach-attach

您还可以创建各种byobu会话byobu -S session1,依此类推。当您回来时,您可以连接到它们中的任何一个。

您可以使用Byobu做更多的事情。用它!一些确定的指南在这里这里


我尝试从基于PuTTY的会话到我的Ubuntu盒子使用byobu,但是我重复了状态行并在显示屏上滚动。尽管在按F6键时它已正确分离,但在我的设置中不是可用的解决方案。
jfmessier

1
@jfmessier这是因为PuTTY不能很好地使用ncurses(基本上是utf-8)。这可以通过以下这个线程来解决这个问题- stackoverflow.com/questions/10731099/...
SiddharthaRT

这太棒了!1.它给了我一个彩色的bash提示,我似乎无法将bash作为默认外壳启用; 2.我可以同时运行2个bot,但仍然需要另一个终端来工作!@SiddharthaRT先生,您值得推荐!
2016年

18

一旦流程开始,您将无法执行此操作,您需要先进行设置,然后再运行长期运行的作业。

您可以使用nohup,但是现代的智慧建议您使用screen或byobu作为登录名,以便分离并保持运行。

Screen的优点是您可以从一台机器上拆下然后再从另一台机器上重新安装,如果您要检查工作日结束后运行的长时间运行的流程,这将非常方便。

屏幕上有一个合理的入门指南

byobu通过菜单等在屏幕顶部提供了易于使用的界面。这也是新版ubuntu上屏幕的当前实现。F2启动新端子F3 / F4来回切换,F6断开连接。键入exit以永久终止终端。


屏风使用TMUX这些天..
scottl

12
“一旦流程开始,您将无法执行此操作,您需要先进行设置,然后再运行长期运行的作业。” -不,您可以disown用来实现这一目标。见@ bassgey的答案

1
在努力学习屏幕和tmux之后。...byobu使我眼泪
HDave

disown如果只需要Ctrl-z,则bg可以将其移至活动终端并移至后台。然后,disown
mimoralea

8

嘿,虽然我同意萤幕是最有效的选择。您可以使用vncserver,然后在其上启动该过程。

同样,如果您唯一的兴趣是使进程运行并且不需要控制,并且最重要的是您不知道需要关闭会话并且已经运行了该进程,那么如果你用bash作为外壳

首先,您需要通过键入Ctrl + Z和bg%1(将数字发送到后台将进程发送到后台)(该数字取决于作业号,通常为1,但是您可以使用命令jobs轻松拉出列表)

最后调用disown命令(后跟Jobid ...与bg命令相同)

这将删除您的外壳程序与后台进程之间的父子关系,从而防止它在外壳程序终止时消失。


2
这个答案是最好的!为什么每个人都在谈论screen,问题是登录后引发的事件,即如何在登录后但启动之前使进程保持运行。很好的答案豪尔赫,您真的帮助了我!:)
jwbensley 2012年

1
简单地bg(没有%1)通常就足够了,因为默认值是当前工作
Walter Tross 2012年

最好有一个全面的答案:先验(预先设置):ascii终端屏幕(旧),tmux(针);X视窗:vnc(旧的,仍保留),xpra(较新),且xpra是无根的。后验(开始后仍然存在):^ Z,不显示,……但我懒得将其充实。
Krazy Glew

8

对于我已经运行了很长时间的单个shell脚本,我将登录并使用'&'在后台运行该过程。

例:

/path/to/my/script &

我已经注销并断开了SSH会话。稍后我登录时,脚本仍在执行,这是通过从脚本连续收集数据来证明的。


3
是的,我想知道screen / tmux比这个简单的解决方案更好。
Mads Skjern

是的,我也可以在我的ubuntu上看到它,但是理论上不应该发生。我不明白为什么
丹尼尔·皮尼奥尔

1
@MadsSkjern因为您不能使用此方法在脚本中输入任何输入。
肯·夏普

1
@MadsSkjern的原因是,如果您&注销并登录到SSH会话后运行这样的进程,则该进程仍将运行,但是您将无法看到该进程的输出(如果脚本回显了某些内容,将看不到它,但是如果它写入文件,文件将在那里)
DarkCygnus

4

您应该查看GNU屏幕,看看它是否对您有帮助。根据您需要应用程序实时运行的方式,它可能会导致问题超出解决的范围,但是至少它可以使您像从未离开过会议一样恢复会话。

如何使用 :

  • 使用该命令screen进行首次启动,滚动浏览介绍消息,您将获得一个终端。
  • Ca Cc开设另一个码头
  • Ca Ck杀死一个终端
  • 您可以使用Ca C-Space和Ca C-Backspace在终端之间循环
  • 如果您只使用两个终端,则Ca方便
  • Ca Cd分离当前的屏幕会话并退出屏幕。然后,您可以screen -r用来恢复该会话。您可以一次拥有多个分离的屏幕会话,在这种情况下,将显示可用会话的列表。

还有许多其他选项,例如拆分屏幕,并且所有快捷方式都可以完全自定义。


3

最简单的答案...

ctrl + z将暂停正在运行的程序

“ bg”将在后台运行


5
如果不放弃进程(使用disownnohup),通常在SSH会话结束后将无法保持进程运行。
伊利亚·卡根

3
在我的Ubuntu服务器上,使用默认设置,它确实可以继续运行!
Mads Skjern

3

最简单的方法是使用在后台运行命令&。然后写:

disown -a

0

尽管每个人都说要使用disown(已经开始执行此过程之后,您唯一的选择),nohup甚至在中运行命令screen,如果您想查看该命令的所有输出,这将非常有用...我是screen..我仍在尝试使用Linux的最新主流发行版,仅将工作置于后台并退出并不会导致所有正在运行的进程消失。必须存在全局设置或其他内容。我正在一些较旧的系统(slackware 12)上尝试此操作,并且测试脚本一直运行,直到我手动将其杀死:

shell$ cat > test.pl

#!/usr/bin/perl
while(1){
     sleep(1);
}
    shell$ perl ./test.pl &
    shell$ exit
    logout
    shell$ ps aux test.pl
    mymom 31337     1  0 13:25 ?        00:00:00 perl ./test.pl
    shell$ 

虽然我同意,screen将是运行最好的办法,即使我的剧本写的日志文件或什么..我从来没有需要使用disown -anohup除非有人出完整的偏执。也许有人可以阐明默认情况下bash的行为方式?也许某些系统管理员更改了大型Shell的默认设置,以防止其用户的进程使系统过载。


如果您有任何其他疑问,
heemayl 2015年


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.