16

Inside a shell script, I need to wait for a window that has a string on its title to appear, do some action, and then wait for it to disappear, and do some other action.

Until yesterday, I had this simple code. The problem with it is that the disk can't be put in a power saving state while the script is left running, and it can be for many hours:

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

Since I decided the mentioned code was insanely waking the disk, I went through the documentation of a few command line tools, and decided on xdotool to wait for the window to appear, and xprop to figure out when the window has vanished:

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

Now I have two new problems with the code above:

  • xdotool not only crashes and gives strange results, as I have workarounded before, but it also sucks about 15% of CPU while left waiting for the window to appear. So that means I got rid of simple code that wakes the disk, to write code that is left wasting the CPU for hours, and my intention was saving power in the first place.
  • xprop -spy will notify me every time I change focus (which I have workarounded through $_line) or create and destroy windows. That wakes the disk more frequently than xdotool.

I'm looking for a simple program that just waits for the window with the title $string to appear or disappear. It can be an existing command line tool, a python script, compilable C code..., but I should be able to integrate it somehow to my script (even if it just writes some information to a fifo)!

15
  • 1
    Wouldn't it make sense to find out why your old code wakes the disk and search for a solution? Something like chroot and ramdisk. I guess strace -f -e trace=file wmctrl -l should be informative. Commented May 7, 2013 at 19:50
  • I'm using fatrace to check for disk wakeups, and it tells me bash reads /bin/sleep and /usr/bin/wmctrl every half second, that's why I'm looking for some program that'll actually wait for window events. Am I missing something? Commented May 7, 2013 at 20:01
  • 1
    reading those wouldn't wake up the disk as they would likely be cached if they were run twice every second. Did you mount your filesystems with noatime? See also btrace from blktrace to investigate sources of disk activity. Commented May 7, 2013 at 20:06
  • 1
    If you haven't looked at it yet xwininfo might be of use, it certainly loads far fewer shared libraries than wmctrl and operates on a level closer to bare X.
    – msw
    Commented May 7, 2013 at 20:32
  • 1
    @msw I'm trying to fix the unfixable, which is an autosave feature for Google Earth (closed sourced and reporting bugs is a waste of time) Commented May 7, 2013 at 20:38

2 Answers 2

8

It might be simpler, and more reliable, to rely on your window manager or X11 to handle this by writing a "real" X11 application.

What you want from the shell is something that registers with the window manager and waits for a desired event type before returning to the shell... it's much more load-friendly if you can avoid looping inside the shell. (Your until xdotool... causes load because there's no delay (sleep) inside the loop.)

Ah... apparently xdotool had that feature added over year ago --sync. That's not available in my current Linux distro (Debian Squeeze), so I haven't tried it out.

The xdotool developer answering a similar question to yours: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ

1
  • Yes, exactly, -sync was supposed to do what I want, but it needs the while because it will eventually crash before the window appears, and wastes too much CPU. I actually compiled xdotool from source because the one from Debian was incredibly slow to type. Writing an application that interacts directly with X is actually beyond me. Thanks, though! Commented May 7, 2013 at 23:12
5

This should give you all (OK: most. What have I forgotten? Sockets?) file system activities which include writes:

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

With this information a working chroot environment can be created in tmpfs (as an action of last resort; maybe symlinks to tmpfs are enough). If the program is started in a RAM chroot then it does not have a chance to wake the disk directly. No write to its file system hierarchy is ever written to disk.

3
  • I believe there are times when reading a file, at least for the first time, will wake the disk too, isn't it? I'm wondering if blktrace would be the right tool for that, but it would require a kernel compilation # CONFIG_BLK_DEV_IO_TRACE is not set :( That is beyond the scope of this question, though. Thank you! Commented May 7, 2013 at 23:19
  • 1
    @TeresaeJunior Sure but who would consider that a problem? This is about keeping the script running all the time not about starting it. And you can create the tmpfs from boot.local / rc.local so that you don't have disk accesses even if you start the script later. I just had a look at blktrace (didn't know that before). That's so terrible I wonder if I will get to sleep tonight... Commented May 8, 2013 at 0:13
  • Yes, I shouldn't really worry about this one anymore, you're right again. But I think I'll also loose this night of sleep compiling the kernel, since I want to check everything that might be waking constantly the disk, not only this particular Google Earth hack :) Commented May 8, 2013 at 0:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .