如何在退出ssh登录后使程序继续运行?

193

1
在我看来,nohup(1)的想法比disown更好,因为disown是BASH的特定于shell的内置,而nohup是coreutils的一部分,很可能存在于任何地方。 - Brian Reiter
使用 batch,例如 echo myprogram its arguments | batch - Basile Starynkevitch
这是你在程序已经开始后如何操作的方法。你需要安装reptyrscreen。通过输入screen来启动一个screen会话。找到你的程序的进程ID:ps aux| grep <myprogramname>。在你的screen会话中,输入reptyr <myprogrampid>,现在你应该能看到你的程序在screen会话中运行。你可以关闭你的ssh会话,screen会继续运行,等待你重新连接。要重新连接,运行screen -ls来查找可用的会话列表,并使用screen -r <mysessionid>重新连接。 - undefined
我在这里记录了一个安全的方法,可以回答这个问题: https://rolfen.github.io/notes/entries/linux/process-detach.html - undefined
6个回答

402

假设您有一个正在前台运行的程序,按下ctrl-Z,然后:

[1]+  Stopped                 myprogram
$ disown -h %1
$ bg 1
[1]+ myprogram &
$ logout
如果只有一个作业,那么您不需要指定作业编号。只需使用disown -hbg命令即可。
上述步骤的说明: 按下ctrl-Z键,系统将挂起运行中的程序,显示作业编号和“已停止”消息,并返回bash提示符。 键入disown -h %1命令(这里我使用了1,但您应该使用在Stopped消息中显示的作业编号),标记该作业使其忽略SIGHUP信号(它不会因为注销而停止)。 接下来,使用相同的作业编号输入bg命令;这将在后台恢复程序运行,并显示确认消息。 现在您可以注销并且程序将继续运行..

7
你能否解释一下每个步骤之后到底发生了什么? - omg
14
你按下 Ctrl-Z 键,系统将暂停运行程序并显示作业号和“已停止”消息,然后返回 bash 提示符。你键入“disown -h %1”命令(这里我用了“1”,但你应该使用在“已停止”消息中显示的作业号),该命令标记该作业以忽略 SIGHUP 信号(它不会因为注销而停止)。接下来,使用相同的作业号键入“bg”命令。这会在后台恢复程序的运行,并显示一条消息进行确认。现在你可以退出登录,程序会继续运行... - Dennis Williamson
4
请注意,当您使用“bg”命令时,结果与在程序末尾添加一个“&”字符并将其放入后台运行是相同的。 它不会输出到标准输出,因此应将其写入文件(nohup会将标准输出重定向到nohup.out或~/nohup.out,如果您没有自行重定向)。 - Dennis Williamson
17
我测试了它,不起作用。当我注销时退出... - Yuda Prawira
4
@ButtleButkus:您可以通过使用“ps x”命令来查看它们。 - Dennis Williamson
显示剩余6条评论

102

你应该尝试使用nohup并在后台运行:

nohup sleep 3600 &

16
再次登录后,有没有办法将这份工作重新置于前台? - Lord Loh.
实际上,默认情况下,它将输出重定向到同一目录中的“nohup.out”文件。 - Gowtham
1
@LordLoh。据我所知,唯一可行的方法是使用 tmuxscreen - James M. Lay
3
这个方法效果好多了,谢谢! 我只需要输入 nohup <我的程序> 然后按下 CTRL-Z + bg 然后就可以退出登录。你可以用另一个 ssh 命令查看 top 来验证它是否还在运行。 - Hulvej
你也可以使用 tail -f nohup.out 实时查看输出,如果需要重新启动,则可以使用 kill 命令杀死该进程的 PID。 - veggiebenz
你应该使用tmux:https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/。不知为何,nohup在我运行`julia myFile.jl`时无法正常工作。我一直收到kill信号和冻结,但是tmux非常完美。 - kilgoretrout

44
我会尝试使用程序 screen

2
虽然screen是一个非常好的工具,但nohup可能更适合这个任务。只有在需要程序交互并能够在以后返回应用程序时才需要使用Screen。老实说,我经常因为与上述问题完全相同的原因而使用screen。 - wvdschel
5
即使是非交互式任务,看到程序没有错误地完成仍然很好。在遇到连接中断的情况下,始终使用屏幕显示也是个好习惯。 - bbigras
10
屏幕的替代方案是tmux - rubo77
7
这是明显的例子,为什么不应该使用仅包含链接的回答。 - mbroshi
我知道这是一个旧答案,但它已被标记为仅链接答案,实际上该链接已失效。是否可能将其扩展以显示如何使用screen的简要示例,也许可以从最初链接的示例中获取(仍可在https://web.archive.org/web/20090106170543/http://www.rackaid.com/resources/linux-tutorials/general-tutorials/using-screen/找到)? - josliber
链接甚至无法更新,因为帖子现在太短了 :/ - Zitrax

19

在后台启动:

./long_running_process options &

在注销之前,先取消挂起作业:

disown

但程序已经开始运行了。 - omg
它会继续以root身份运行吗? - omg
1
如果程序已在控制台上运行,并且您可以访问它正在运行的控制台,请按“Ctrl + Z”将其发送到后台,然后取消关联新创建的作业。只要进程以root身份启动,除非它自己放弃权限,否则它将继续以root身份运行。 - diciu
但是该命令名为“disown”,这不是说root将放弃该程序,程序将不会继续以root身份运行吗? - omg
在使用“Ctrl+Z”停止进程后,您可以使用“bg”将其发送到后台,然后再使用“disown”命令。 - diciu
2
"disown"只是为了放弃对任务的控制,不会改变进程的特权。 - diciu

14

2
链接已经失效,但我猜这个链接应该差不多:https://www.cyberciti.biz/tips/nohup-execute-commands-after-you-exit-from-a-shell-prompt.html - chjortlund

3
您可以使用 screen,分离和重新连接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接