1.) 简单回答:不,pid 本身是正确的,但与运行窗口的 yad 进程不匹配。yad 总是有两个 pid,因为 yad 显然是由一些包装脚本调用的,而不是在从命令行或脚本中输入“yad”时直接调用。这可能是特定于发行版的。
$ yad -- info & echo $!
29523
$ pidof yad
29524
$ ps x | grep 'yad' | grep -v 'grep'
29523 pts/0 S 0:00 /bin/bash /usr/local/bin/yad -- info
29524 pts/0 S 0:00 /usr/bin/yad -- info
确认:
$ cat /usr/local/bin/yad
#!/bin/bash
/usr/bin/yad "$@" 2>/dev/null
所以选项 -x 将显示两个 pid。
$ pidof -x yad
29524 29523
这在处理多个存在的 yad 实例时无济于事(例如,用户多次调用脚本);ps中存在一些相同的yad进程对:
$ yad -- info
$ yad
$ yad -- info
$ ps x | grep 'yad' | grep -v 'grep'
22928 pts/0 S 0:00 /bin/bash /usr/local/bin/yad -- info
22929 pts/0 S 0:00 /usr/bin/yad -- info
23131 pts/0 S 0:00 /bin/bash /usr/local/bin/yad
23132 pts/0 S 0:00 /usr/bin/yad
24633 pts/0 S 0:00 /bin/bash /usr/local/bin/yad -- info
24634 pts/0 S 0:00 /usr/bin/yad -- info
2.) 我从上面的分析得出的可靠地找到特定 yad 窗口的两个 pid 的解决方案是:
# get yad pid of specific yad window
yad_pid_before="$(pidof -x yad) "
yad --info & \
sleep 1
yad_pid="$(pidof -x yad)"
if [ "$yad_pid_before" != " " ]; then
while read -d' ' item
do
yad_pid="$(echo "$yad_pid" | sed "s/$item//g")"
done <<<"$yad_pid_before"
fi
#testing
echo -e "yad recent window pids:\t$yad_pid\nsleeping 6s before closing."
sleep 6
kill $yad_pid
问题描述:
Yad 至少在某些发行版中开始使用包装脚本。所以“杀死$!” 将失败。替代“ps x”没有提供足够的信息来区分使用相同选项调用的多个 yad 窗口。
解决方案说明:
所有现有 yad 进程的 pid 都存储在“$yad_pid_before”中,就在执行新的 yad 窗口之前。为了查找字符串中的最后一项,有意且需要空白后缀字符。用于获取脚本 pid 的选项 -x 是强制性的。
第二个(重要的)pid 不会立即出现,并且无法提前注册,因此“sleep 1”等待它。
在新的 yad 窗口启动后,将所有 yad pid 存储在“$yad_pid”中。
从“yad_pid”中删除任何存在于“$yad_pid_before”中的pid,同时从here-string循环遍历列表。
循环是必需的,并且仅在“$yad_pid_before”中至少存在一项时才执行,否则 sed 命令将失败。条件分支负责这一点。
结果变量“$yad_pid”包含两个最近的 pid,现在可用于脚本中的 kill 命令以关闭在第二行打开的特定 yad 窗口。之前或之后未打开的其他 yad 窗口均不受影响。
至少适用于原始问题中指定的 bash 和 yad 版本。
如果有人可以为此提供更优雅的解决方案,请解释。