$! 未捕获的 bash 进程的 PID

$! 未捕获的 bash 进程的 PID

虽然脚本的这一部分工作正常:

geany &
pid=$!
...
kill -KILL $pid

相反,事实并非如此。

lxterminal &
pid=$!
...
kill -KILL $pid

看起来 bash 进程仍然在后台,但它没有被$pid.如何获取终端窗口的PID,以便之后可以杀死该进程?

注意:我也尝试通过其名称来杀死它,但该--title选项引发了与PROMPT_COMMAND.

答案1

当然lxterminal会分叉一个子进程。想一想。该子进程是连接到模拟终端的交互式 shell通过lxterminal(或任何随选项提供的替代程序-e)。它反过来又会产生进一步的孙进程,具体取决于人们在该 shell 中实际执行的操作。

Killinglxterminal会关闭它使用的伪终端的主端,对于从端而言,这看起来像是终端挂起。从属端被交互式 shell 视为其控制终端。因此SIGHUP,如果终端-hupcl设置打开,shell 应该会看到正常的终端挂起,并生成会话领导者。该会话领导者就是该 shell 进程。

会话领导者负责会话内的作业控制,并将挂断信号传递给其所有作业。显然,如果您已经disown通过该 shell 运行了 ed 或nohupped 它,则会话领导者不会传递挂断信号,并且即使lxterminal已终止且伪终端的主端已关闭,某些内容仍将继续运行。这就是什么disownnohup

您需要弄清楚为什么当伪终端挂起时,您在交互式会话中运行的任何内容都不会消失。你没有告诉我们那是什么,我们也没有心灵感应。因此,除了一般性地说明会话领导者 shell 的设计用途之外,没有什么可建议的。

答案2

正如@9000 已发表评论,lxterminal可能会再次分叉。获取新分支的进程 ID 比较困难,这就是$!不起作用的原因。

答案3

这可能有效。但我没有测试过。

lxterminal &
pid=$!
kill -KILL "$(ps -ho ppid,pid | grep ^$pid | cut -d' ' -f2)"
  • ps -ho ppid,pid获取PPID(父PID)和当前运行进程的PID。
  • 然后grep ^$pid过滤掉不是由 分叉的内容$pid,因此由lxterminal后台的 分叉。
  • 最后,cut选择孙子的PID。

相关内容