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