等待 X 窗口出现/消失(以正常的方式)

等待 X 窗口出现/消失(以正常的方式)

在 shell 脚本中,我需要等待标题上有字符串的窗口出现,执行一些操作,然后等待它消失,然后执行一些其他操作。

直到昨天,我有了这个简单的代码。它的问题是,当脚本运行时,磁盘无法进入省电状态,而且可能会持续几个小时:

while :; do
    until wmctrl -l | grep -q "$string"; do   # until
        sleep 0.5
    done
    : do action 1

    while wmctrl -l | grep -q "$string"; do   # while
        sleep 0.5
    done
    : do action 2
done

由于我认为上述代码疯狂地唤醒了磁盘,因此我浏览了一些命令行工具的文档,并决定xdotool等待窗口出现,并xprop确定窗口何时消失:

while :; do
    # we use `until' because sometimes xdotool just crashes
    until xdotool search -sync -all -onlyvisible -pid $pid -name "$string"; do
        :
    done

    # xdotool isn't trustworthy either, so check again
    wmctrl -l | grep -q "$string" ||
        continue

    : do action 1

    xprop -spy -root _NET_CLIENT_LIST_STACKING | while read line; do
        if [[ ! ${_line:-} || $_line = $line ]]; then
            _line=$line
            continue
        else
            _line=$line
            if wmctrl -l | grep -q "$string"; then
                continue
            else
                : do action 2
                break
            fi
        fi
    done
done

现在我对上面的代码有两个新问题:

  • xdotool不仅会崩溃并给出奇怪的结果(正如我之前解决过的那样),而且在等待窗口出现时还会消耗大约 15% 的 CPU 资源。因此,这意味着我放弃了唤醒磁盘的简单代码,转而编写浪费 CPU 数小时的代码,而我的目的首先是节省电量。
  • xprop -spy每次我改变焦点(我已经通过解决方法$_line)或创建和销毁窗口时都会通知我。这比 xdotool 更频繁地唤醒磁盘。

我正在寻找一个简单的程序,它只等待带有标题的窗口$string出现或消失。它可以是现有的命令行工具、python 脚本、可编译的 C 代码……,但我应该能够以某种方式将其集成到我的脚本中(即使它只是将一些信息写入 fifo)!

答案1

依靠窗口管理器或 X11 通过编写“真正的”X11 应用程序来处理此问题可能更简单、更可靠。

您想要从 shell 获得的是向窗口管理器注册并在返回 shell 之前等待所需的事件类型...如果您可以避免在 shell 内循环,那么它会更加负载友好。 (你的until xdotool...原因是负载,因为循环内没有延迟(睡眠)。)

啊...显然xdotool一年前就添加了该功能--sync。这在我当前的 Linux 发行版 (Debian Squeeze) 中不可用,所以我还没有尝试过。

xdotool 开发人员回答了与您类似的问题: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ

答案2

这应该为您提供所有(好吧:大多数。我忘记了什么?套接字?)文件系统活动,其中包括写入:

strace -f command 2>&1 | 
  grep -e '^open.*O_CREAT' \
    -e ^write   \
    -e ^mkdir   \
    -e ^rmdir   \
    -e ^unlink  \
    -e ^rename  \
    -e ^chmod   \
    -e ^link    \
    -e ^symlink \
    -e ^mknod

有了这些信息,就可以在 tmpfs 中创建一个工作的 chroot 环境(作为最后的手段;也许到 tmpfs 的符号链接就足够了)。如果程序在 RAM chroot 中启动,则它没有机会直接唤醒磁盘。对其文件系统层次结构的任何写入都不会写入磁盘。

相关内容