`disown -h` 和 `nohup` 的工作效果是否相同?

`disown -h` 和 `nohup` 的工作效果是否相同?

disown

  • 当 shell 终止时,导致 shell 不向其拒绝的作业发送 SIGHUP,并且

  • 从 shell 的作业控制中删除已拒绝的作业。

第一个是第二个的结果吗?换句话说,如果从 shell 启动的进程以任何方式从 shell 的作业控制中删除,那么当 shell 终止时,shell 不会向该进程发送 SIGHUP 吗?

disown -h 仍然将进程置于 shell 的作业控制之下。是否意味着disown -h让进程仍然接收从shell发送的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 -h如果我们忽略它们在使用终端方面的差异,那么它们的工作效率是否nohup相同?

谢谢。

答案1

nohup并且disown -h不是确切地一样的东西。

使用disown,可以从当前交互式 shell 中的作业列表中删除进程。jobs启动后台进程并运行后运行disown不会将该进程显示为 shell 中的作业。被拒绝的作业在退出时不会收到HUP来自 shell 的 a (但请参阅最后的注释)。

使用 时disown -h,作业不会从作业列表中删除,但HUP如果退出,shell 不会向它发送信号(但请参阅末尾的注释)。

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

不同之处在于,无论谁发送信号,进程都会nohup忽略。HUP被否认的进程并不是发送一个HUP信号通过外壳,但仍可能从eg 发送信号kill -s HUP <pid>,并且不会忽略这一点。

请注意,HUP仅在以下情况下才会发送到 shell 的作业:

  • shell 是登录 shell 并且huponexit设置了 shell 选项,或者
  • shell 本身接收HUP信号。

手册中的相关内容bash(我的重点):

信号

[...]

shell默认退出收到一份SIGHUP。在退出之前,交互式 shell 会重新SIGHUP向所有正在运行或已停止的作业发送 。发送停止的作业SIGCONT以确保它们收到 SIGHUP.为了防止 shell 将信号发送到特定作业,应使用内置函数将其从作业表中删除disown(见下文)或 使用SHELL BUILTIN COMMANDS标记为不接收。SIGHUPdisown -h

如果huponexitshell 选项已设置为shopt,则在交互式登录 shell 退出时向所有作业bash发送 a 。SIGHUP

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

如果没有选项,请jobspec从活动作业表中删除每个作业。 [...]如果-h给出该选项,则每个jobspec都是没有删除从表中,但被标记为SIGHUP如果 shell 收到一个SIGHUP。 [...]

有关的:

答案2

他们是不同的:

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

  • nohup 忽略 HUP。然后,进程关闭时本应传递到终端的任何内容都会转入文件nohup.out

    nohup 由 POSIX 定义,而 disown 则不是。

相关内容