如果您已经使用'&'分叉了,什么时候需要'nohup'?


26

首先,这个问题是相关的,但绝对不同于这个非常好的问题:

nohup,disown和&之间的区别

我想了解一些东西:当我做“&”时,我在分叉吗?

做“ nohup ...&”曾经有用还是简单而足够?

有人可以说明您将使用“&”并且仍想使用“ nohup”的情况吗?


1
您已阅读接受的答案及其评论主题吗?他们确实解释了什么nohup。您对哪一部分感到困惑?
吉尔(Gilles)'所以

3
@Gilles:这可能对很明显,因为您碰巧熟悉了这些东西(见过您的代表)...但是,首先,我所做的链接中接受的答案并没有说明使用两者的nohup和“&” ......我敢肯定我的问题是不够清楚,并与其他不同的是,和两个伟大的答案在这里似乎证明; )此外,您是否真的暗示我确实很想链接到另一个问题,但没有阅读已接受的答案!?
Cedric Martin

Answers:


32

首先,每次执行命令时,shell都会派生一个新进程,而不管您是否运行它&&仅表示您在后台运行它。

请注意,这不是很准确。一些命令,例如cdshell函数,通常不会派生新进程。type cmd通常会告诉您cmd是外部命令还是shell函数。type type告诉您type本身就是一个shell函数。

nohup是不同的。它告诉新过程要忽略SIGHUP。它是关闭父外壳程序时内核发送的信号。

要回答您的问题,请执行以下操作:

  1. 运行emacs & (默认情况下应在单独的X窗​​口中运行)
  2. 在父外壳上,运行exit

您会注意到emacs,尽管在后台运行该窗口,但该窗口仍被杀死。这是默认行为,nohup正好用于修改它。

在后台运行作业(使用&bg,我敢打赌其他shell也具有其他语法)是shell的功能,其源于现代系统对多任务的能力。相反分叉为要启动的每个程序,现代shell一个新的shell实例(bashzshksh,...)将不得不管理程序(或列表的能力的工作)。一次只能将其中一个放在前台,这意味着它会成为shell的焦点。我希望有人可以进一步扩展在前台运行的进程和在后台运行的进程之间的区别(主要进程是stdin/ stdout)。

无论如何,这都不会影响子进程的反应方式SIGHUPnohup做。


+1为你们两个人提供了很好的答案...但是我仍然很困惑...在回答我的问题之前,我尝试过这样做:也许我的(很旧的)Debian Linux安装程序配置不正确,但是如果我“ emacs& ”,然后键入“ exit”,只有我的xterm退出:emacs停留在那里。
Cedric Martin

Emacs非常复杂,可以自行处理SIGHUP。缺省情况下,进程仅在SIGHUP上退出。许多“守护程序”程序(例如ntpd或inetd)将在SIGHUP上重新读取其配置,而不是退出。我本人是vim家伙,所以我对emacs没有太多经验。
布鲁斯·埃迪格

3
emacs没什么特别的。外壳程序通常SIGHUP在外壳程序自身接收时发送给其子进程SIGHUP,而不是在外壳程序正常退出时发送给其子进程。bash有一个选项huponexit,使它SIGHUP在退出时发送给孩子,但默认情况下未启用。 gnu.org/software/bash/manual/bashref.html#Signals
Keith Thompson

你好。首先,很好的解释。我试图通过运行一个进程来验证您的论文,&并通过运行来关闭我的shell exit。该过程仍在运行。关于为什么它没有被杀死的任何想法?还是我在这里想念什么?
阿里·耶尔玛兹(AliYılmaz),

您正在运行什么流程?
rahmu

16

这样做有用nohup ... &吗?是。如果您只是使用&,在“后台”启动一个进程,那么该新进程仍然具有原始shell的“进程组”中的成员资格。如果该外壳程序或进程组收到某些信号(例如SIGHUP),则默认情况下会退出。这意味着,如果&从xterm或rxvt或其他窗口终端仿真器启动的外壳程序运行进程,则在关闭窗口时,后台进程将得到SIGHUP。大多数随便编写的代码都不处理SIGHUP,因此退出。

如果这样做nohup ... &,该nohup命令会将SIGHUP设置为忽略,然后执行该命令。新执行的命令将保留nohup设置的信号掩码,除非该命令自行执行一些信号处理。如果关闭xterm或rxvt或其他命令,则内核会将SIGHUP传递给命令的进程,该进程将被忽略。它一直在运行。

nohup在关闭xterm或注销后,对它执行命令可使它继续运行。


对不起-你失去了我。您是说使用&with nohup可以使命令在某些情况下(仅使用using nohup不会)运行吗?这似乎与这里的答案相冲突:unix.stackexchange.com/a/288064/1822
Mike B,

2
@MikeB-“&”执行通常的fork / set Things / exec系统调用,以将命令“置于后台”。也就是说,没有跳转的命令是异步运行的。将nohup在之前做一些事情exec()的系统调用,使派生进程忽略某些信号。因此,是的,“&”将允许命令在普通旧版本不允许的某些情况下运行nohup。例如,关闭与执行nohup的外壳程序关联的xterm或注销。
Bruce Ediger

-1

如果您在linux操作系统上在后台运行程序(带有&作为后缀),然后注销,即使该程序将继续运行,请尝试:

  ping google.com > ping_result  &

重新登录后,检查输出文件ping_result中的行数,该行数将继续增加,表示该行仍在运行,但是已被告知将关闭。那么nohup命令的用途是什么。

如上nohup emac &-> 所述,另一个场景==> emac在系统注销后应该继续运行,但是在重新登录后并没有显示运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.