$ nohup foo
和
$ foo &
有什么区别? #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,则可能会发生,例如xterm
或ssh
创建的终端,并且通过关闭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提示,而不是阻塞直到程序结束。 nohup
和disown
在很大程度上无关;它们抑制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
评论
还有foo&!应该等于一开始就放弃它。Bash不支持&!.
您也可以使用set -m启用作业控制。参见unix.stackexchange.com/questions/196603/…
我很想看看setid,以及它与disown和nohup的关系
“守护进程”是一个目的,但在某些情况下,可能有人需要启动一个长期运行的进程,并确保在关闭笔记本电脑/丢失热点/等时,该进程不会被杀死。长期运行的构建,数据迁移,Web爬网等