2013-03-24 129 views
156

nohup myprocess.out &myprocess.out &设置myprocess.out在后台运行。在关闭终端后,该过程仍在运行。 他们之间有什么区别?nohup和&符号有什么区别

+0

你在用什么外壳?该行为在壳牌 – shx2 2013-03-24 06:47:35

+1

bash中变化。我知道为什么现在根据@nemo的答案。 – Yarkee 2013-03-24 07:20:35

+0

@Yarkee如果答案适合您的问题,请将问题标记为已接受(答案投票下方的复选框),以免它悬而未决。你应该这样做所有你的问题:) – nemo 2013-03-24 18:22:21

回答

215

nohup捕获挂断信号(请参阅man 7 signal),而&符号不包含(除非shell以这种方式配置或根本不发送SIGHUP)。

通常,当使用&运行命令并在之后退出shell时,shell会用挂断信号(kill -SIGHUP <pid>)终止子命令。这可以通过使用nohup来阻止,因为它捕获信号并忽略信号,从而永远达不到实际应用。

如果您使用bash,您可以使用命令shopt | grep hupon来确定您的shell是否将SIGHUP发送到其子进程中 。如果它关闭,进程将不会终止,因为它似乎是你的情况。关于bash如何终止的更多信息可以在 找到here

有些情况nohup不起作用,例如当您启动过程重新连接 的SIGHUP信号,因为它是如此here案件。

25

myprocess.out &将使用子shell在后台运行进程。如果当前shell被终止(例如通过注销),则所有子壳也被终止,所以后台进程也将被终止。 nohup命令忽略了HUP信号,因此即使当前shell已终止,subshel​​l和myprocess.out仍将继续在后台运行。另一个区别是单独使用&不会重定向stdout/stderr,因此如果有任何输出或错误,则会显示在终端上。 nohup另一方面将stdout/stderr重定向到nohup.out或$ HOME/nohup.out。

+2

我运行'myprocess.out&'并退出shell。但是,当我使用'ps aux | grep myprocess.out'在其他shell中,我仍然可以找到“myprocess.out”。这意味着该进程仍在运行,不会被终止。 – Yarkee 2013-03-24 05:20:03

+0

@amit_g当使用'kill -9'杀死父shell时,不会有SIGHUP,因为这需要父shell处理SIGKILL,它不能。 – nemo 2013-03-24 05:22:58

+2

检查shopt |在其他答案中提到的grep hupon。 – 2013-03-24 05:25:09

19

使用&符号(&)将在子进程(child到当前bash会话)中运行该命令。但是,当您退出会话时,所有子进程都将被终止。使用的nohup +号(&)将做同样的事情,不同的是在会话结束时,子进程的父将改为“1”,这是“初始化”过程,从而保持该儿童

被杀害。

18

大多数情况下我们使用ssh登录到远程服务器。如果你启动一个shell脚本并注销,那么这个进程就会被终止。 即使从shell注销后,Nohup也可以帮助继续在后台运行脚本。

Nohup command name & 
eg: nohup sh script.sh & 

Nohup捕获HUP信号。 Nohup不会自动将作业置于后台。我们需要明确地使用&

+0

谢谢。没有期待你的答案,但它在这里的事实是伟大的。它回答了我没有问的问题:D – 2015-01-15 11:17:03

1

nohup命令是一个信号屏蔽实用程序并捕获挂断信号。 &符号不能捕获挂断信号。当使用&运行命令并退出shell时,shell将用挂断信号终止sub命令。这可以通过使用nohup来防止,因为它捕获信号。 Nohup命令接受内核发送给进程的挂起信号,并将其封锁。Nohup命令在用户想要启动长时间运行的应用程序注销或关闭启动进程的窗口时很有用。这些操作中的任何一个通常都会提示内核在应用程序中挂起,但nohup包装将允许该过程继续。 使用&符号将在子进程和当前bash会话的这个子进程中运行该命令。当您退出会话时,该进程的所有子进程都将被终止。 &符号与活动shell的作业控制有关。这对于在后台运行会话中的进程很有用。

2

纠正我,如果我错了

nohup myprocess.out & 

nohup的渔获挂断信号,这意味着当终端关闭,它将发送一个过程。

myprocess.out & 

进程可以运行,但一旦终端关闭就会停止。

nohup myprocess.out 

过程甚至能够运行终端关闭,但你可以通过按ctrl + z在终端停止进程。 Crt + z如果&已存在,则不起作用。