如果我启动后台进程然后注销,它会继续运行吗?

如果我启动后台进程然后注销,它会继续运行吗?

在与同事进行了长时间的讨论后,我提出这个问题,我真的很想得到澄清。

我启动了一个后台进程,方法是将“ &”附加到命令行,或者使用CTRL-Z“ ”停止它并在后台恢复它bg。然后我注销。

会发生什么?

我们非常确定它应该被 SIGHUP 杀死,但这并没有发生;再次登录后,该进程正常运行,并pstree显示它已被“采纳” init

这是预期的行为吗?

但是,如果是,那么该nohup命令的目的是什么?看起来,不管有没有该命令,该进程无论如何都不会被终止……


编辑1

更多细节:

  • 该命令是从 SSH 会话启动的,而不是从物理控制台启动的。
  • 命令已启动没有 nohup和/或&;然后它被暂停CTRL-Z并在后台恢复bg
  • ssh 会话没有删除。确实有一个注销(“ exit”命令)。
  • 该过程是一个scp文件复制操作。
  • 再次登录后,pstree显示该进程正在运行并且是 的子进程init

编辑2

更清楚地陈述问题:将一个进程置于后台(使用&bg)是否会使其忽略SIGHUP,就像nohup命令一样?


编辑3

我尝试手动发送一个SIGHUPscp:它退出了,所以它肯定不会忽略信号。

然后我尝试再次启动它,将其置于后台并注销:它被“采用”init并继续运行,当我重新登录时我发现它在那里。

我现在很困惑。看来SIGHUP注销时根本没有发送任何消息。

答案1

找到答案。

对于 BASH,这取决于huponexitshell 选项,可以使用内置shopt命令查看和/或设置。

看起来这个选项默认是关闭的,至少在基于 RedHat 的系统上是这样。

更多信息BASH 手册页

默认情况下,shell 在收到 SIGHUP 后退出。在退出之前,交互式 shell 会将 SIGHUP 重新发送给所有正在运行或已停止的作业。已停止的作业将收到 SIGCONT 以确保它们收到 SIGHUP。要防止 shell 向特定作业发送信号,应使用 disown 内置命令将其从作业表中删除(请参阅下面的 SHELL 内建命令),或使用 disown -h 将其标记为不接收 SIGHUP。

如果已使用 shopt 设置了 huponexit shell 选项,则当交互式登录 shell 退出时,bash 会向所有作业发送 SIGHUP。

答案2

我同意 Warner 的观点,只是想补充一点,你可以使用内置的“disown”命令阻止 shell 发送 SIGHUP。bash 手册页中有很好的描述。

答案3

您可以使用命令禁止启动命令并将输出重定向到 nohup 输出文件。来自 nohup 手册页:

nohup - run a command immune to hangups, with output to a non-tty

另一个选择是使用屏幕命令。使用 screen 的好处是您可以稍后重新连接到该进程。

答案4

如果您注销(Ctrl-Dexit),它将继续运行。但如果您关闭终端窗口,后台进程将收到SIGHUP。如果您失去与服务器的连接,它们也会收到SIGHUP。本地运行的 shell 也是如此(只是您不能失去与本地 shell 的连接)。

相关内容