Подождите, пока окно X появится / исчезнет (в здравом смысле)

11

Внутри сценария оболочки мне нужно дождаться появления окна с заголовком, выполнить какое-либо действие, а затем дождаться его исчезновения и выполнить какое-либо другое действие.

До вчерашнего дня у меня был этот простой код. Проблема в том, что диск не может быть переведен в состояние энергосбережения, пока скрипт остается запущенным, и это может занять много часов:

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% процессорного времени, пока остается в ожидании появления окна. Это означает, что я избавился от простого кода, который будит диск, от написания кода, который тратит впустую процессорное время на несколько часов, и в первую очередь я намеревался экономить энергию.
  • xprop -spyбудет уведомлять меня каждый раз, когда я изменяю фокус (который я обошел $_line) или создаю и уничтожаю окна. Это пробуждает диск чаще, чем xdotool.

Я ищу простую программу, которая просто ждет $stringпоявления или исчезновения окна с заголовком . Это может быть существующий инструмент командной строки, скрипт на python, компилируемый код на C ..., но я должен иметь возможность каким-то образом интегрировать его в мой скрипт (даже если он просто записывает некоторую информацию в fifo)!

Тереза ​​и Джуниор
источник
1
Разве не имеет смысла выяснять, почему ваш старый код пробуждает диск, и искать решение? Что-то вроде chroot и ramdisk. Я думаю, strace -f -e trace=file wmctrl -lдолжно быть информативным.
Хауке Лагинг
Я использую fatraceдля проверки дискового пробуждения, и он сообщает мне bashчитает /bin/sleepи /usr/bin/wmctrlкаждые полсекунды, поэтому я ищу какую-то программу, которая будет фактически ждать оконных событий. Я что-то пропустил?
Тереза ​​и Джуниор
1
чтение этих файлов не приведет к пробуждению диска, так как они, вероятно, будут кэшированы, если их запускать дважды в секунду. Вы монтировали свои файловые системы с noatime? Смотрите также btraceот blktraceисследовать источники активности диска.
Стефан Шазелас
1
Если вы еще не посмотрели на него, оно xwininfoможет быть полезным, оно, безусловно, загружает гораздо меньше разделяемых библиотек, чем wmctrl, и работает на уровне ближе к голому X.
msw
1
@msw Я пытаюсь исправить нефиксированное, которое является функцией автосохранения для Google Earth (закрытые источники и сообщения об ошибках - пустая трата времени)
Teresa e Junior

Ответы:

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). Если программа запускается в chroot памяти, то у нее нет возможности напрямую разбудить диск. Никакая запись в его иерархию файловой системы никогда не записывается на диск.

Хауке Лагинг
источник
Я полагаю, что бывают случаи, когда чтение файла, по крайней мере в первый раз, тоже разбудит диск, не так ли? Мне интересно, подойдет ли blktraceдля этого подходящий инструмент, но для этого потребуется компиляция ядра # CONFIG_BLK_DEV_IO_TRACE is not set:( Хотя это выходит за рамки этого вопроса. Спасибо!
Teresa e Junior
1
@TeresaeJunior Конечно, но кто будет считать это проблемой? Речь идет о том, чтобы постоянно запускать скрипт, а не о его запуске. И вы можете создать tmpfs из boot.local/, rc.localчтобы у вас не было доступа к диску, даже если вы запустите скрипт позже. Я только что посмотрел blktrace(не знал, что раньше). Это так ужасно, мне интересно, если я
засну
Да, я больше не должен беспокоиться об этом, ты снова прав. Но я думаю, что я также потеряю эту ночь сна во время компиляции ядра, так как хочу проверить все, что может постоянно будить диск, не только этот конкретный взлом Google Планета Земля :)
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потому что в конечном итоге он вылетит до того, как появится окно, и будет тратить слишком много ресурсов процессора. Я на самом деле скомпилировал xdotoolиз исходного кода, потому что тот из Debian был невероятно медленным для ввода. Написание приложения, которое напрямую взаимодействует с X, на самом деле мне не подходит. Спасибо хоть!
Тереза ​​и Джуниор