如何获取mousepad进程PID?脚本报错及PID复用问题咨询
首先咱们得把问题根源理清楚:
Mousepad默认是单实例应用——也就是说,如果你已经打开过一个Mousepad窗口,再执行mousepad /path/to/file时,它不会启动新进程,而是让正在运行的Mousepad进程打开一个新窗口。这直接导致你的脚本里$!拿不到值:$!只能捕获当前shell刚启动的后台子进程的PID,这里根本没创建新进程,所以$!是空字符串,自然会触发kill: '': not a pid or valid job spec的错误。
你提到的"两个独立进程窗口使用相同PID"其实是个误解——这不是两个进程,是同一个进程管理多个窗口,所以PID是同一个,这是单实例应用的典型行为。
下面给你两个可行的解决方案,按需选择:
方案1:强制启动Mousepad新实例
Mousepad支持--new-instance参数,用它可以强制启动全新进程,这样你的脚本就能正常拿到PID了。修改后的脚本如下:
#!/bin/bash # 用--new-instance强制启动新进程,&放到后台运行 mousepad --new-instance /etc/iptables/rules & pid=$! echo "$pid" # 等待该进程结束 while kill -0 "$pid"; do sleep 0.5 done # 进程结束后执行规则恢复 iptables-restore < /etc/iptables/rules
这个方案逻辑简单,和你原脚本思路一致,不需要额外安装工具。
方案2:跟踪特定编辑窗口(不启动新实例)
如果你不想开新的Mousepad实例,只想等用户关闭当前编辑的那个窗口后再执行恢复,可以借助窗口管理工具wmctrl(需要先通过包管理器安装,比如apt install wmctrl或pacman -S wmctrl)。脚本思路是:打开窗口后找到对应窗口ID,等待这个窗口消失。
#!/bin/bash # 打开Mousepad编辑规则文件 mousepad /etc/iptables/rules & # 给窗口一点加载时间 sleep 1 # 获取包含文件名"rules"的Mousepad窗口ID(可根据实际标题调整匹配规则) window_id=$(wmctrl -l | grep "rules" | awk '{print $1}') # 循环检测该窗口是否存在 while wmctrl -l | grep -q "$window_id"; do sleep 0.5 done # 窗口关闭后恢复规则 iptables-restore < /etc/iptables/rules
注意:如果窗口标题不包含文件名,可能需要调整grep的匹配内容,比如用grep "Mousepad"匹配所有Mousepad窗口,但这样会等所有Mousepad窗口关闭才执行,你可以根据需求灵活调整。
最后补充原脚本的小问题:原脚本里mousepad命令没加&放到后台,就算是第一次启动Mousepad,$!也拿不到PID——因为命令是前台运行的,shell会等它结束才继续执行后面的代码,pid=$!永远不会被执行到。所以哪怕是首次启动,也需要加&让进程在后台运行,$!才能捕获到PID。
内容的提问来源于stack exchange,提问作者Tcll

