285

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

4

7 回答 7

366

nohup捕获挂断信号(参见 参考资料man 7 signal),而 & 符号没有捕获(除非 shell 以这种方式配置或根本不发送SIGHUP)。

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

如果您使用的是 bash,您可以使用该命令shopt | grep hupon来确定您的 shell 是否将 SIGHUP 发送到其子进程。如果它关闭,进程将不会被终止,就像你的情况一样。更多关于 bash 如何终止应用程序的信息可以在这里找到。

在某些情况下nohup不起作用,例如当您启动的进程重新连接SIGHUP信号时,就像这里的情况一样。

于 2013-03-24T05:04:20.617 回答
63

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

于 2013-03-24T05:12:21.437 回答
47

大多数时候我们使用 ssh 登录到远程服务器。如果您启动 shell 脚本并注销,则该进程将被终止。即使您从 shell 注销后,Nohup 也有助于在后台继续运行脚本。

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

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

于 2014-01-07T07:48:54.847 回答
33

使用与号 (&) 将在子进程(当前 bash 会话的子进程)中运行命令。但是,当您退出会话时,所有子进程都将被杀死。

使用 nohup + & 符号 (&) 将做同样的事情,除了当会话结束时,子进程的父进程将更改为“1”,即“init”进程,从而防止子进程被杀死。

于 2013-07-09T15:36:08.847 回答
8

如我错了请纠正我

  nohup myprocess.out &

nohup捕获挂断信号,这意味着它将在终端关闭时发送一个进程。

 myprocess.out &

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

nohup myprocess.out

进程甚至可以在终端关闭时运行,但是您可以通过在终端中按ctrl+来停止该进程。+如果存在则不工作。zCrtz&

于 2017-02-07T04:51:36.220 回答
3

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

于 2015-12-20T18:10:04.720 回答
3

在很多情况下,环境之间的微小差异会影响您。这是我最近遇到的一个。这两个命令有什么区别?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

答案和往常一样——这取决于。

nohup 捕获挂断信号,而 & 符号没有。

挂机信号是什么?

SIGHUP - 在控制终端上检测到挂起或控制进程死亡(值:1)。

通常,当使用 & 运行命令并随后退出 shell 时,shell 将使用 hangup 信号终止子命令(如 kill -SIGHUP $PID)。这可以使用 nohup 来防止,因为它会捕获信号并忽略它,因此它永远不会到达实际的应用程序。

很好,但就像在这种情况下总是有“但是”。当 shell 配置为根本不发送 SIGHUP 时,这些启动方法之间没有区别。

如果您使用的是 bash,您可以使用下面指定的命令来确定您的 shell 是否向其子进程发送 SIGHUP:

~ $ shopt | grep hupon

而且 - 在某些情况下 nohup 不起作用。例如,当您启动的进程重新连接 NOHUP 信号时(它在内部完成,在应用程序代码级别)。

在所描述的情况下,在自定义服务启动脚本中调用了第二个脚本,该脚本在没有 nohup 命令的情况下设置和启动正确的应用程序时,缺乏差异让我感到很困惑。

在一个 Linux 环境中,一切运行顺利,在第二个环境中,应用程序在第二个脚本退出后立即退出(检测到这种情况,当然花了我更多的时间,然后你可能会认为 :stuck_out_tongue:)。

将 nohup 作为启动方法添加到第二个脚本后,即使脚本退出,应用程序也会继续运行,并且此行为在两个环境中都变得一致。

于 2019-11-04T10:46:02.217 回答