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


11

在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
找出为什么您的旧代码唤醒磁盘并寻找解决方案不是很有意义吗?诸如chroot和ramdisk之类的东西。我想strace -f -e trace=file wmctrl -l应该能提供很多信息。
Hauke Laging,

fatrace用来检查磁盘唤醒,它告诉我bash读取/bin/sleep/usr/bin/wmctrl每半秒,这就是为什么我要寻找一些实际上会等待窗口事​​件的程序。我想念什么吗?
Teresa e Junior

1
读取这些内容不会唤醒磁盘,因为如果它们每秒运行两次,则可能会被缓存。您是否使用noatime挂载了文件系统?另请参阅btraceblktrace以调查磁盘活动的来源。
斯特凡Chazelas

1
如果您还没有看过它xwininfo可能会有用,它肯定会比wmctrl加载更少的共享库,并且运行的水平更接近裸X。–
msw

1
@msw我正在尝试解决不可修复的问题,这是Google Earth的自动保存功能(关闭源并报告错误是在浪费时间)
Teresa e Junior

Answers:


4

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

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中启动,则它没有机会直接唤醒磁盘。对其文件系统层次结构的写入都不会写入磁盘。


我相信有时至少是第一次读取文件时也会唤醒磁盘,不是吗?我想知道这是否blktrace是正确的工具,但是它需要内核编译# CONFIG_BLK_DEV_IO_TRACE is not set:( 但是,这超出了此问题的范围。谢谢!
Teresa e Junior

1
@TeresaeJunior当然可以,但是谁会考虑这个问题呢?这是关于始终保持脚本运行而不是启动脚本。而且,您可以从boot.local/ 创建tmpfs,rc.local以便即使稍后启动脚本也没有磁盘访问权限。我只是看了一下blktrace(以前不知道)。那真是太糟糕了,我想知道我今晚是否可以入睡……
Hauke Laging

是的,我再也不用担心这个了,您又是对的。但我想我也将在今晚的睡眠中放松编译内核,因为我想检查可能不断唤醒磁盘的所有内容,不仅是这种特殊的Google Earth hack :)
Teresa e Junior

6

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

从外壳程序中获取的是在窗口管理器中注册的东西,并在返回到外壳程序之前等待所需的事件类型...如果可以避免在外壳程序中循环,那么它对负载更友好。(until xdotool...因为循环内部没有延迟(睡眠),所以会造成负载。)

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

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


是的,确切地说,-sync应该执行我想要的操作,但是它需要使用while它,因为它最终会在窗口出现之前崩溃,并浪费过多的CPU。我实际上是xdotool从源代码编译的,因为Debian的代码键入速度非常慢。编写直接与X交互的应用程序实际上超出了我的范围。不过谢谢!
Teresa e Junior
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.