究竟是什么决定了退出shell时后台作业是被杀死还是被杀死?


12

这个问题已经拿出了相当 一个 不少真的 很多),但我发现答案是一般不完整。一般的问题是“为什么我退出/杀死ssh时为什么/不杀死我的工作?”,这就是我所发现的。第一个问题是:以下信息的一般性如何?对于现代Debian linux,以下内容似乎是正确的,但我缺少一些内容;别人需要知道什么?

  1. 只有huponexit设置了该选项的情况下,关闭ssh连接时,所有通过ssh连接打开或未通过壳打开的Shell子进程都会被SIGHUP杀死:运行shopt huponexit以查看是否为真。

  2. 如果huponexit为true,则可以使用nohupdisown将该进程与Shell分离,以使它在退出时不会被杀死。或者,使用运行screen

  3. 如果huponexit为false(这最近至少在某些Linux上的默认设置),则后台注销的作业不会在正常注销时被杀死。

  4. 但是,即使它huponexit为false,如果ssh连接被终止或断开(不同于正常注销),则后台进程仍将被终止。可以通过disownnohup如(2)中那样避免。

  5. (a)父进程为终端的进程与(b)将stdin,stdout或stderr 连接到终端的进程之间存在一些区别。我不知道(a)而不是(b)的过程会发生什么,反之亦然。

最后一个问题:如何避免行为(3)?换句话说,默认情况下,在Debian中,后台进程会在注销后自行运行,而不是在ssh连接被终止后运行。无论连接是正常关闭还是终止,我都希望进程发生同样的事情。还是,这是个坏主意?

编辑:保持工作被杀死的另一种重要方法,在两种情况下都可行(?)是通过screen运行它们。但是,问题更多是关于了解何时杀死事物以及何时杀死事物:例如,有时人们希望在注销时杀死工作。

多个线程: - 对信号(SIGHUP),作业和控制终端澄清 - https://serverfault.com/questions/117152/do-background-processes-get-a-sighup-when-logging-off - 继续SSH关闭SSH时的后台任务/作业 - 关闭SSH会话后,置于后台的作业会继续运行吗? - 防止关闭SSH客户端后停止正在运行的后台进程 - 如何通过SSH启动进程,以便在断开连接后继续运行? - 无法使远程作业在OS X上运行 - 关闭SSH连接

Answers:


1

流程并非“被SIGHUP杀死”-至少在严格意义上不是这样。而是,当连接断开时,将向终端的控制过程(在本例中为Bash)发送挂断信号*,通常简称为“ HUP信号”,或简称为SIGHUP。

现在,当进程接收到信号时,它可以按其想要的任何方式处理该信号**。大多数信号(包括HUP)的默认设置是立即退出。但是,程序可以随意忽略信号,甚至可以运行某种信号处理程序功能。

Bash选择最后一个选项。它的HUP信号处理程序检查“ huponexit”选项是否为真,如果是,则将SIGHUP发送到其每个子进程。Bash仅在完成后退出。

同样,每个子进程在收到信号时可以自由地做任何想做的事情:将其设置为默认值(即立即死亡),忽略它或运行信号处理程序。

Nohup仅将子进程的默认操作更改为“忽略”。但是,子进程一旦运行,就可以自由更改其对信号的响应。

我认为,这就是为什么即使您使用nohup运行某些程序也会死掉的原因:

  1. Nohup将默认操作设置为“忽略”。
  2. 该程序在退出时需要进行某种清理,因此它安装了SIGHUP处理程序,附带地覆盖了“ ignore”标志。
  3. 当SIGHUP到达时,处理程序将运行,清理程序的数据文件(或需要执行的所有操作)并退出程序。
  4. 用户不知道或不关心处理程序或清除,只是看到程序没有进行任何退出而退出了。

这就是“ disown”出现的地方。被ash拒绝的进程永远不会发送HUP信号,而不管huponexit选项如何。因此,即使程序设置了自己的信号处理程序,也不会实际发送信号,因此该处理程序也不会运行。但是请注意,如果程序尝试向注销的用户显示一些文本,则将导致I / O错误,无论如何这都可能导致程序退出。

*而且,是的,在您询问之前,“挂断”术语是UNIX的拨号大型机时代遗留下来的。

**无论如何,大多数信号。例如,SIGKILL 总是使程序立即终止。


2

第1-4点是正确的。关于第5点,我一无所知。关于最后一点,一个精美的应用程序screen可以让您让所有进程正常运行,而无论您如何终止连接。屏幕位于存储库中。

屏幕的man描述不容易阅读,但是它指出:

调用screen时,它将创建一个带有外壳的单个窗口(或指定的命令),然后不碍事,以便您可以正常使用该程序。然后,您可以随时创建带有其他程序的新(全屏)窗口(包括更多的shell),杀死现有窗口,查看窗口列表,打开和关闭输出日志记录,复制和粘贴文本在窗口之间切换,查看回滚历史记录,以任何希望的方式在窗口之间切换,等等。所有窗口彼此完全独立地运行其程序。 当程序的窗口当前不可见时,即使整个屏幕会话都与用户终端分离,程序仍继续运行。程序终止时,屏幕(默认情况下)会杀死包含该程序的窗口。如果此窗口在前台,则显示切换到先前的窗口;如果没有,屏幕将退出。

我已经强调了最重要的部分:您可以使用Ctrl + a + d命令分离窗口,然后您可以终止会话/注销会话,现在分离的窗口将继续运行,并且内部程序仍在运行。当您重新连接时,例如通过启动新的ssh会话,命令screen -r将恢复先前分离的屏幕会话,所有输出到标准错误/输出都清晰可见。

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.