【问题标题】:How can a background bash script exit the running shell?后台 bash 脚本如何退出正在运行的 shell?
【发布时间】:2013-09-07 10:45:54
【问题描述】:

在启用作业控制并关闭标准输入的情况下在后台运行 bash 脚本将退出 PARENT shell。怎么会这样?

为了演示做这个background_bash_script:

#!/bin/bash
set -m
ruby -e "puts :here"

然后在 bash 中运行它 - 它会退出你运行它的 shell。ruby 命令无关紧要,尽管它看起来必须是命令而不是 bash 内置(例如 awk --version 有效,但 @987654324 @ 才不是)。为了看得更清楚,我一直在另一个 bash 实例中运行它。完整的会话如下所示。

parent: PS1='child: ' bash
child: ./background_bash_script <&- &
[1] 3893
child: here
exit
parent:

令人困惑!

【问题讨论】:

  • 即使没有关闭标准输入,我也会得到这种行为。
  • 您是否在某个时候运行过trap exit CHLD? :)
  • @dannysauer - 哈,不。没有自找的有趣的事情:)

标签: bash shell stdin jobs


【解决方案1】:

似乎正在发生的事情是,在脚本中运行set -m 之后,运行的下一个命令被强制位于前台进程组中,这会将原始 shell 带出前台进程组。一旦该进程退出,运行脚本的 shell 现在就在前台进程组中,但是一旦该 shell 退出,原始 shell 不会将自己放回前台进程组,因为它在后台运行脚本。因此,您现在拥有一个位于后台进程组中的交互式 shell。

如果您在脚本末尾设置 sleep 以使其不会立即退出,您会在这里看到一些奇怪的行为。当您在后台运行脚本时,您会返回终端提示符,但现在您的交互式 shell 不在前台进程组中!一旦您尝试键入任何内容,shell 就会退出。我不确定究竟是什么机制导致退出。由于 shell 在后台,任何对终端读取或写入字符的尝试都会导致 SIGTTIN 或 SIGTTOU,但这些信号不会导致 shell 在我的测试中退出。

【讨论】:

  • Wowzers。我不知道你是怎么想出来的,但似乎很有可能。您是否在关闭标准输入的情况下进行了调查?也许当子外壳位于前台并退出时,父外壳会出现但重新附加子标准输入(已关闭)。也许父级退出是因为它获得了一个封闭的标准输入?
  • @SimonChiang:我没有发现关闭标准输入是相关的。我使用的是 Linux,我检查了 /proc/[pid]/stat 的内容以获取有关会话、进程组等的信息。
猜你喜欢
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
相关资源
最近更新 更多