it-swarm.cn

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

假设我从ssh会话中启动了一堆进程。是否可以在保持这些进程在远程计算机上运行的同时终止ssh会话?

610
Olivier Lalonde

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

tmux优于screen有很多原因,这里只是一些例子:

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

基本功能

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

  • ssh进入远程机器
  • 通过在Shell中键入tmux来启动tmux
  • 在已启动的tmux会话中启动所需的进程
  • 通过键入来保留/分离tmux会话 Ctrl+b 然后 d

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

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

tmux可以比在单个会话中处理单个窗口做更高级的事情。有关更多信息,请查看man tmuxtmux GitHub页面 。特别是 这里是FAQ 关于screentmux之间的主要区别。

703
tongpu

选项1:Nohupname__

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

Nohup long-running-command &

它专门为此而制作,它甚至将stdout记录到Nohup.log

man Nohup

选项2:bgname__

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

bg

将最近暂停的任务放到后台,允许它继续运行。

然后快速disownname__应该在您注销后保持进程运行。

screenname__和其他人可以做到,但这不是他们的目的。我推荐Nohupname__用于您知道要留下的任务,bgname__用于已经运行且不想重新启动的任务。

请记住,两者都是bash特定的。如果你不使用bash,那么命令可能会有所不同。

284
coteyr

你可以使用screen来做到这一点。

输入man screen以了解更多信息或阅读本文 屏幕手册页

简单场景:

  • ssh进入你的遥控盒。键入screen然后启动所需的进程。

  • 按 Ctrl - A 然后 Ctrl - D。这将“分离”您的屏幕会话,但让您的进程保持运行。您现在可以退出远程控制台。

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

199
Lincoln

屏幕和Nohup是更好的方法,但如果你必须分离已经没有屏幕或Nohup运行的进程,你可以运行disown命令。

disown [-ar] [-h] [jobspecname__… |pidname__… ]

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

通过disown,您可以关闭终端并在机器上运行进程。

81
bassgey

我被困在一个大型的MV中,所以我无法停止该过程,设置屏幕然后再次启动它。我设法通过基本上执行以下步骤退出运行进程的ssh会话:

  1. ssh [服务器]
  2. 命令
  3. Ctrl+Z
  4. bG
  5. disown [进程pid可选,默认为last]
  6. 出口

步骤3暂停当前进程(例如我的'mv'命令)。
步骤4将暂停的进程置于后台并恢复它。
第5步允许您拒绝该过程。** 要获取作业列表,只需键入jobsbefore即可。


** 关于disown(来自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.
50
Chaos

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

屏风

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

Sudo aptitude install byobu

使用yum,你做到了

su -c 'yum install byobu'

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

使用byobu

您可以在使用ssh连接后在主机上运行byobu来启动byobu。这将为您提供如下所示的Shell:

image-byobu

你也可以在带有-X选项的Ubuntu机器上使用Byobu终端,轻松拥有一个完美的工作byobu。

用法:

键入byobu启动byobu。

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

关于byobu的最好的部分是,你不必实际杀死终端中运行的进程离开终端。你可以简单地将screen/tmux(byobu的骨架)发送到后台,并在下次来时恢复:

  • 离开byobu并保持运行(分离)按F6。
  • 下次你来的时候,只需做byobu然后你就会回到原来的位置。

    byobu-detach-attach

您还可以通过byobu -S session1等创建各种byobu会话。当你回来时,你可以连接到他们中的任何一个。

您可以使用Byobu做更多事情。用它!一些权威指南是 这里 ,或 这里

21
SiddharthaRT

一旦进程开始,您就无法执行此操作,您需要在运行长时间运行的作业之前进行设置。

您可以使用 Nohup 但现代智慧建议您使用屏幕或byobu作为登录,这样您就可以分离并保持运行状态。

屏幕的优点是,如果要检查超出工作日结束的长时间运行的进程,您可以从一台机器上拆下并从另一台机器上重新连接,这很方便。

有一个合理的入门 屏幕指南 这里。

byob 在菜单等屏幕上放置一个易于使用的界面。它也是新版ubuntu屏幕的当前实现。 F2启动新的终端F3/F4来回切换和F6断开连接。键入exit以实际终止终端。

18
Richard Holloway

对于我在很长一段时间内运行的单个Shell脚本,我将登录,并使用“&”在后台运行该过程。

例:

/path/to/my/script &

我已经注销并断开了我的SSH会话。当我稍后登录时,脚本仍在执行,正如脚本中的连续数据收集所证明的那样。

8
user108430

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

此外,如果你唯一的意图是让流程运行而不需要控制它,并且完全最重要的是你不知道你需要关闭会话并且你已经运行了这个过程,如果你没有运气的话你使用bash作为Shell

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

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

这将删除Shell和后台进程之间的父子关系,防止它在Shell终止时死亡。

8
Jorge Gutierrez

你应该看看 GNU Screen 并看看它是否对你有帮助。根据您的应用程序如何实时运行,可能会导致更多问题而不是解决,但至少它会让您恢复会话,就像您从未离开过一样。

如何使用 :

  • 使用命令screen作为第一次启动,滚动介绍消息,你应该交给一个终端。
  • C-a C-c打开另一个终端
  • C-a C-k杀死一个终端
  • 您可以使用C-a C-Space和C-a C-Backspace来循环终端
  • 如果你大多只使用两个终端,那么C-a C-a很方便
  • C-a C-d分离当前屏幕会话并退出屏幕。然后,您可以使用screen -r来恢复该会话。您可以同时拥有多个分离的屏幕会话,在这种情况下,您将显示可用会话列表。

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

4
T. Verron

最简单的答案......

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

“bg”将在后台运行它

3
Roop

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

disown -a
3
Zibri

虽然每个人都说使用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的默认设置,以防止用户的进程超载系统?

0
Dan Gullage