0

I'm trying to close a yad window from within bash script using kill command, but pids do allways mismatch. Same on command line.

$ yad & pid_01=$!
$ kill $pid_01
bash: kill: (31879) - Kein passender Prozess gefunden
$ echo $(pidof yad)
31880
$ echo $!
31879

No other yad processes running.

  1. What's going on here? Why is this pid allways wrong? (so the window fails to get closed)
  2. How can I find reliably the pid of a specific yad window when more than one yad process is running? Or is there another way to close this yad window from within a bash script? Since “kill $(pidof yad)” will probably randomly close another yad window.

I'm confused a little since I didn't notice before other programs to have this issue.

Any help appreciated.


GNU bash, Version 5.0.3(1)-release (i686-pc-linux-gnu) yad --version 0.40.0 (GTK+ 3.24.5)

4

1 回答 1

0

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 版本。

如果有人可以为此提供更优雅的解决方案,请解释。

于 2021-04-20T02:50:19.383 回答