`disown -h`和`nohup`是否有效地相同?


18

disown

  • 导致shell在终止时不将SIGHUP发送到其未完成的工作,并且

  • 从Shell的作业控件中删除不相关的作业。

第一个是第二个的结果吗?换句话说,如果以某种方式从外壳启动的进程从外壳的作业控件中删除了,那么在外壳终止时外壳将不会将SIGHUP发送给该进程吗?

disown -h 仍然将进程保持在Shell的作业控制之下。这是否意味着disown -h使进程仍然接收从外壳发送的SIGHUP,但是将进程设置为SIGHUP的动作是“忽略”?听起来类似于nohup

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

disown -hnohup工作实际上是一样的,如果我们无视他们在使用终端的区别?

谢谢。


此处未讨论的另一个区别是,如果您不使用nohup,则需要自己将stdin / stdout / stderr重定向为远离TTY(如果您的原始外壳连接到其中)。(OTOH,实际上,我认为这种方法比依赖于令人讨厌的硬编码默认值更好./nohup.out)。
查尔斯·达菲

Answers:


21

nohupdisown -h没有确切的同样的事情。

使用disown,将从当前交互式Shell中的作业列表中删除一个进程。jobs启动后台进程并运行后运行,disown将不会将该进程显示为外壳中的作业。HUP退出的作业在退出时不会从外壳接收到(但请参阅结尾处的注释)。

使用时disown -h,不会将作业从作业列表中删除,但是如果外壳HUP退出,则外壳不会向其发送信号(但请参阅结尾处的注释)。

nohup实用程序将忽略HUP信号并启动给定的实用程序。该实用程序继承了信号掩码,nohup因此也将忽略该HUP信号。当shell终止时,该进程将保留为的子进程nohup(并nohup重新绑定到init)。

不同之处在于,无论谁发送信号,该过程都以nohup忽略开始HUP。六亲不认过程只是不发送一个HUP信号,由外壳,但是仍然可以从例如发送信号kill -s HUP <pid>并不会忽略这一点。

请注意,HUP只有在以下情况下才会发送到外壳的作业:

  • 该外壳程序是登录外壳程序,并且huponexit已设置外壳程序选项,或者
  • 外壳本身会收到HUP信号。

bash手册中的相关内容(我强调):

讯号

[...]

默认情况下SIGHUP shell 在收到时退出。在退出之前,交互式外壳程序会将send重新发送SIGHUP给所有正在运行或已停止的作业。发送已停止的作业SIGCONT以确保它们接收到 SIGHUP。为了防止外壳将信号发送到特定作业,应使用disown内置功能(请参阅SHELL BUILTIN COMMANDS下文)将其从作业表中删除,或将其标记为不SIGHUP 使用接收disown -h

如果使用huponexit设置了shell选项,则在退出交互式登录shell时shoptbash将向SIGHUP所有作业发送 。

disown [-ar] [-h] [jobspec ... | pid ... ]

如果没有选项,请jobspec从活动作业表中删除每个选项。[...]如果-h给出了选项,jobspec不会从表中删除每个选项,而是将其标记SIGHUP为如果shell收到则不会发送给作业SIGHUP。[...]

有关:


我得到bash: disown: nohup: no such job与同为sleep5disown nohup sleep 5 &。您从最后一句话的第二个命令是什么意思?
Ruslan '18

@Ruslan是的,我错过了&在那里(和顺序nohupdisown也是错误的)。谢谢。现在将更新。
库萨兰达


@Tim对不起,答案的编辑过多。我花了好一会儿才明白。我完成了。
库沙兰南达

谢谢。disown通过从Shell作业列表中删除子代,使Shell不会将SIGHUP发送给子代。如何disown -h实现相同?
蒂姆(Tim)

4

他们是不同的:

  • disown从活动作业表中删除作业。然后继续当前的工作。使用-h时,不会将过程发送给SIGHUP。当它收到SIGHUP时,将与包含它的外壳一起死掉。

  • nohup忽略HUP。然后,本应通过过程关闭传递到终端的任何内容都将转至文件nohup.out

    nohup是由POSIX定义的,而unown不是。


您是什么意思,“死于包含它的外壳”?杀死父进程本身并不会杀死孩子。关闭终端的程序通常会由于与尝试与终端PTY上附加的文件句柄进行交互相关的失败而死亡,但是,如果将stdin / stdout / stderr重定向到其他位置,则不会发生这种情况。
查尔斯·达菲
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.