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

pet*_*arp 16 linux ssh process

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

  1. 当 ssh 连接关闭时,所有通过 ssh 连接打开的 shell 的后台或非后台子进程都会被 SIGHUP 杀死,仅当huponexit设置了该选项时:运行shopt huponexit以查看这是否为真。

  2. 如果huponexit为 true,则您可以使用nohupdisown将进程与外壳分离,以便在退出时不会被杀死。或者,使用screen.

  3. 如果huponexit为 false,这至少是目前某些 linux 上的默认值,那么在正常注销时不会终止后台作业。

  4. 即使huponexit是假的,那么如果 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 连接

Hid*_*eld 5

进程不会“被 SIGHUP 杀死”——至少,严格意义上不是这样。相反,当连接断开时,终端的控制进程(在本例中为 Bash)会发送一个挂断信号*,该信号通常缩写为“HUP 信号”,或简称为 SIGHUP。

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

Bash 选择最后一个选项。它的 HUP 信号处理程序检查“huponexit”选项是否为 true,如果是,则向其每个子进程发送 SIGHUP。只有当它完成后,Bash 才会退出。

同样,每个子进程在收到信号时可以自由地执行任何操作:将其设置为默认值(即立即终止)、忽略它或运行信号处理程序。

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

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

  1. Nohup 将默认操作设置为“忽略”。
  2. 该程序在退出时需要进行某种清理,因此它安装了一个 SIGHUP 处理程序,顺便覆盖了“忽略”标志。
  3. 当 SIGHUP 到达时,处理程序运行,清理程序的数据文件(或任何需要完成的操作)并退出程序。
  4. 用户不知道也不关心处理程序或清理,只是看到程序尽管 nohup 还是退出了。

这就是“否认”的用武之地。无论 huponexit 选项如何,被 Bash 否认的进程都不会发送 HUP 信号。因此,即使程序设置了自己的信号处理程序,信号也永远不会真正发送,因此处理程序永远不会运行。但请注意,如果程序尝试向已注销的用户显示某些文本,则会导致 I/O 错误,从而可能导致程序退出。

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

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


归档时间:

查看次数:

4179 次

最近记录:

6 年,2 月 前