$ nohup foo



$ foo &
有什么区别?

评论

还有foo&!应该等于一开始就放弃它。

Bash不支持&!.

您也可以使用set -m启用作业控制。参见unix.stackexchange.com/questions/196603/…

我很想看看setid,以及它与disown和nohup的关系

“守护进程”是一个目的,但在某些情况下,可能有人需要启动一个长期运行的进程,并确保在关闭笔记本电脑/丢失热点/等时,该进程不会被杀死。长期运行的构建,数据迁移,Web爬网等

#1 楼

首先让我们看一下如果从没有&(并且没有任何重定向)的交互式shell(连接到终端)启动程序会发生什么情况。因此,假设您刚刚键入了foo

创建了运行foo的进程。
该进程从shell继承了stdin,stdout和stderr。因此,它也连接到同一终端。
如果外壳程序接收到SIGHUP,它还将向进程发送SIGHUP(这通常导致进程终止)。
否则,外壳程序将等待(被阻塞) ),直到进程终止或停止。

现在,让我们看一下如果将进程置于后台,即键入foo &会发生什么情况:

正在运行foo的进程被创建。
该进程从shell继承stdout / stderr(因此它仍会写入终端)。
原则上,该进程也继承stdin,但是一旦尝试从stdin读取,它就会
被置于外壳程序管理的后台作业列表中,这尤其意味着:

它与jobs一起列出,并且可以使用%n进行访问(其中n是作业号) )。
可以使用fg将其转换为前台作业,在这种情况下,它将继续进行,就好像您不会在上面使用&一样(如果我t由于尝试从标准输入读取而停止,因此现在可以继续从终端读取。)
如果外壳程序收到SIGHUP,它也将SIGHUP发送到进程。根据外壳以及可能为外壳设置的选项,终止外壳时,它还会向过程发送一个SIGHUP



现在,disown从Shell的作业列表中删除了该作业,因此上述所有子点不再适用(包括Shell发送SIGHUP的进程)。但是请注意,它仍然连接到终端,因此如果终端被破坏(如果是pty,则可能会发生,例如xtermssh创建的终端,并且通过关闭xterm或终止SSH终止控制程序连接),则程序将尝试从标准输入读取或写入标准输出时立即失败。
另一方面,nohup的作用是有效地将过程与终端分开:

它关闭标准输入(该程序即使在前台运行也无法读取任何输入。它不会暂停,但会收到错误代码或EOF。)。
它将重定向标准输出和文件nohup.out的标准错误,因此如果终端发生故障,程序不会失败,无法写入标准输出,因此不会丢失任何写入过程。
它防止了该过程接收SIGHUP(因此名称)。

请注意,nohup不会删除专业人士来自shell作业控制的成功,并且也没有将其置于后台(但是由于前台nohup作业或多或少没有用,因此通常应使用&将其置于后台)。例如,与disown不同,shell仍会告诉您nohup作业何时完成(当然,除非shell之前已经终止)。
所以总结一下:


&将作业置于后台,也就是说,使其在尝试读取输入时阻塞,并使外壳程序不等待其完成。

disown从Shell的作业控件中删除了该进程,但仍将其连接到终端。结果之一是该外壳程序不会向其发送SIGHUP。显然,它只能应用于后台作业,因为在前台作业运行时您无法输入它。

nohup断开进程与终端的连接,将其输出重定向到nohup.out并将其与SIGHUP隔离。效果之一(命名之一)是该进程不会接收任何发送的SIGHUP。它完全独立于作业控制,并且原则上也可以用于前台作业(尽管不是很有用)。


评论


+1谢谢。一起使用disown,nohup和&会发生什么?

– Tim
2015年4月2日,14:27

如果同时使用这三个选项,则该进程在后台运行,从Shell的作业控件中删除,并且实际上已与终端断开连接。

– Celtschk
15年4月2日在15:46

谢谢。我想知道为什么当启动它的终端关闭时,仅凭nohup不能免于关闭谷歌浏览器进程吗?

– Tim
2015年4月2日在16:19

disown%1和disown -h%1有什么区别?第二个将保留为常规作业(但忽略HUP信号),直到终端退出?

–方案
2015年11月3日,0:07

也许值得包括(foo&)子shell

– Jiggunjer
16年8月25日在12:32



#2 楼

使用&会使程序在后台运行,因此您将获得一个新的shell提示,而不是阻塞直到程序结束。 nohupdisown在很大程度上无关;它们抑制SIGHUP(挂断)信号,因此在控制终端关闭时不会自动终止程序。当作业第一次开始时,nohup会执行此操作。如果您没有在作业开始时对其进行修改,则可以使用nohup来修改正在运行的作业。不带任何参数的情况下,它会修改当前的工作,这是刚刚被后台执行的工作

评论


nohup和disown之间的细微差别:disown命令会将其从作业列表中删除; Nohup不会。

– Shawn J. Goff
2010年11月9日在16:41

可以说nohup和disown都可以抑制SIGHUP,但是方式不同。 nohup使程序最初忽略该信号(程序可能会对此进行更改)。 nohup还尝试安排该程序不具有控制终端,以便在终端关闭时内核不会将其发送给SIGHUP。抛弃纯粹是在壳内部;它导致外壳终止时不发送SIGHUP。

–吉尔斯'所以-不再是邪恶的'
2010年11月9日,18:26

@吉尔斯,您的评论本身值得一提。

– Lesmana
2010年11月10日在18:30

只是对@ ShawnJ.Goff的注释的澄清,该注释与不愿从作业列表中删除作业有关。如果您未指定选项,则会将其从作业列表中删除。但是,如果指定-h选项,则不会从表中删除每个jobspec。相反,它使得如果外壳程序收到SIGHUP,则不会将SIGHUP发送到作业。

– Tacotuesday
13年11月13日在6:54



为了明确起见,使用&不会给您终端,它会使stdin与进程分离并使其在后台运行,但是stdout和stderr都仍附加到当前tty上。这意味着您可能将来自不同程序的文本混合在一起,如果您尝试gimp&并在尝试将tty用于其他操作时出现很多GTK +错误,可能会很烦人。

–坦白
2014年6月5日21:18

#3 楼

这是我的经验,尝试使用非终止命令(例如tail)在后台运行办公室。对于此示例,我将使用sleep 100



#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100



我看到了办公日志/通过按Ctrl-C办公停止


nohup ..&

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100



我看不到办公室日志/按Ctrl-C办公台停止


并消失

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100



我看到了办公记录/按Ctrl-C办公停止


setsid ..&

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100



我看到了办公室日志/通过按Ctrl-C菜单不停止


要节省空间,请执行以下操作:nohup setsid ..:不显示日志/办公室在Ctrl-C上不停止nohup& disown结尾:不显示日志/办公室在Ctrl-C

评论


我感谢提及setid并显示在特定情况下会发生什么的工作,但我希望看到更彻底的答案。特别是每种解决方案的区别和相似之处,既可见(在关闭外壳或终端时会发生什么,输出将到达何处……),又是不可见的(在幕后做事及其含义)。公认的答案是一个很好的基础。

– YoungFrog
17年3月21日在20:58

@YoungFrog我会同意这一点!

– Marinos An
17年3月21日在21:06

对我而言,使用nohup⟨command⟩和disown不会在Ctrl + C上停止。

–k.stm
18年6月27日在20:23



@ k.stm您尝试过办公室吗? soffice命令似乎有所不同。因此,我考虑将其作为规则例外添加到此处。例如当使用:nohup ..&时,按Ctrl-c通常不会导致命令停止,但是带有办公室就可以。我等到有人踩到这并解释为什么用办公室时会发生这种情况:)

– Marinos An
18年6月28日在13:29

@MarinosAn是的,我做到了。我运行了nohup soffice&,然后按了Ctrl + C。没有发生任何意外。

–k.stm
18年7月5日在10:58