从终端在后台运行程序

OVE*_*ONE 167 command-line bash console process

如何在 shell 的后台运行程序,并能够在保持程序运行的同时关闭 shell?假设我的 UI 有问题,或者出于某种原因,我需要从终端窗口启动一个程序,例如nm-applet

nm-applet
Run Code Online (Sandbox Code Playgroud)

当它启动时,它占据终端窗口的前景。

有没有什么简单的方法可以在后台运行程序而无需让终端保持打开状态或让它占据整个终端?

在那一点上,我确实找到了一种从终端运行程序并允许其他输入的方法,方法是&在命令中附加一个与号 ( ) ,如下所示:

nm-applet &
Run Code Online (Sandbox Code Playgroud)

但这没有多大用处,因为一旦终端关闭,在终端中启动的任何进程都会被终止。                                                                        

Oli*_*Oli 203

我最近开始喜欢setsid。它开始看起来好像您只是在终端上运行某些东西,但您可以断开连接(关闭终端)并且它会继续运行。

这是因为该命令实际上是分叉出来的,当输入到达当前终端时,它由一个完全不同的父级拥有(关闭终端后它仍然存在)。

一个例子:

setsid gnome-calculator
Run Code Online (Sandbox Code Playgroud)

我也很偏爱disown它可以用于将进程与当前树分开。您将它与背景符号结合使用:

gnome-calculator & disown
Run Code Online (Sandbox Code Playgroud)

我也刚刚学会了用括号生成子shell。这个简单的方法有效:

(gnome-calculator &)
Run Code Online (Sandbox Code Playgroud)

当然还有nohup你提到的。我并不疯狂,nohup因为它倾向于在~/nohup.out没有我要求的情况下写信。如果你依赖它,它可能适合你。

nohup gnome-calculator
Run Code Online (Sandbox Code Playgroud)

对于长期进程,还有screen其他虚拟终端多路复用器之类的东西可以使连接之间的会话保持活动状态。这些可能并不真正适用于您,因为您只想临时访问终端输出,但如果您想稍后返回并查看最新的终端活动, screen 可能是您的最佳选择。

互联网上到处都是screen教程,但这里有一个简单的快速入门:

  • **未来用户注意**:`nohup.out` 的创建可以通过将 stdout 和 sterr 重定向到 `/dev/null` 来抑制,如下所示:`nohup firefox &> /dev/null &` (5认同)
  • @nuttyaboutnatty 在它自己的 shell 会话中包装了全部内容:`sh -c "sleep 10s && cvlc '/home/omm.ogg'" & disown`。这几乎是我对所有事情的解决方案,以确保它正确分叉。 (4认同)

gei*_*rha 66

这是我会采用的两种方式。首先,不要从终端运行它;点击Alt+F2打开运行对话框,然后从那里运行它(不带 &)。

从终端运行

nm-applet &
Run Code Online (Sandbox Code Playgroud)

但不要自己关闭终端。也就是说,不要点击 X 按钮关闭,也不要从菜单栏中使用 File -> Exit。如果您以这种方式关闭终端,它将向在其中运行的 bash 发送一个 HUP(挂起)信号,后者又将向其所有子进程发送 HUP 信号(这就是 nohup 在这种情况下起作用的原因)。

相反,通过运行exit或点击Ctrl+退出 shell D。然后 bash 将否认其子进程,然后退出,让后台进程仍在运行。当 bash 退出时,终端失去了它的子进程,所以它也会关闭。

一次性完成所有操作:

nm-applet & exit
Run Code Online (Sandbox Code Playgroud)


des*_*gua 18

正如你所指出的,你可以运行

nohup nm-applet &  
Run Code Online (Sandbox Code Playgroud)

关闭终端时忽略结束信号。没有问题。

  • 我想知道当你双击一个图标或程序时它是如何从 UI 工作的。 (2认同)

krl*_*mlr 15

许多其他答案遗漏的一件事是如何分离当前阻塞 shell 的正在运行的进程。在大多数终端和 shell 中,Ctrl+Z将停止正在运行的进程并使您返回到输入提示。然后,您可以发出

bg
Run Code Online (Sandbox Code Playgroud)

将正在运行的进程发送到后台。问题

fg
Run Code Online (Sandbox Code Playgroud)

而是将正在运行的进程放回前台。

编辑:我后来发现的这个答案中的更多细节。


Ser*_*nyy 9

使用?exec PROGRAM &> /dev/null & ?允许子shell的PID被接管PROGRAM。我已经用几个不同的程序多次测试了这种方法。关闭原始终端对新生成的程序没有影响

小演示:

$ # this is before running
$ (exec firefox &> /dev/null &)
$ # and look, we still in side the terminal and can continue working
Run Code Online (Sandbox Code Playgroud)