虽然脚本的这一部分工作正常:
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 或nohup
ped 它,则会话领导者不会传递挂断信号,并且即使lxterminal
已终止且伪终端的主端已关闭,某些内容仍将继续运行。这就是什么disown
和nohup
做。
您需要弄清楚为什么当伪终端挂起时,您在交互式会话中运行的任何内容都不会消失。你没有告诉我们那是什么,我们也没有心灵感应。因此,除了一般性地说明会话领导者 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。