可以持续 pid 变量 $!使用 yad 时出错?

问题描述

我正在尝试使用 kill 命令从 bash 脚本中关闭 yad 窗口,但 pid 总是不匹配。命令行也一样。

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

没有其他 yad 进程正在运行。

  1. 这是怎么回事?为什么这个pid总是错误的? (所以窗口无法关闭
  2. 当多个 yad 进程正在运行时,如何可靠地找到特定 yad 窗口的 pid?还是有另一种方法可以从 bash 脚本中关闭这个 yad 窗口?由于“kill $(pidof yad)”可能会随机关闭一个 yad 窗口。

我有点困惑,因为我之前没有注意到其他程序有这个问题。

感谢任何帮助。


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

解决方法

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

so 选项 -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 版本。

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...