Aguarde a janela X aparecer / desaparecer (de maneira sã)

11

Dentro de um script de shell, preciso aguardar a exibição de uma janela com uma string no título, executar alguma ação e esperar que ela desapareça e executar outra ação.

Até ontem, eu tinha esse código simples. O problema é que o disco não pode ser colocado em um estado de economia de energia enquanto o script permanece em execução, e isso pode ocorrer por muitas horas:

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

Como decidi que o código mencionado estava despertando insanamente o disco, consultei a documentação de algumas ferramentas de linha de comando e decidi xdotoolesperar a janela aparecer e xpropdescobrir quando a janela desapareceu:

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

Agora eu tenho dois novos problemas com o código acima:

  • xdotoolnão apenas trava e dá resultados estranhos, como eu já havia contornado antes, mas também suga cerca de 15% da CPU enquanto aguarda a janela aparecer. Isso significa que me livrei do código simples que ativa o disco, para escrever o código que resta desperdiçando a CPU por horas, e minha intenção era economizar energia em primeiro lugar.
  • xprop -spyme notificará toda vez que eu mudar o foco (que eu contornei $_line) ou criar e destruir janelas. Isso ativa o disco com mais frequência que o xdotool.

Estou procurando um programa simples que apenas aguarde a janela com o título $stringaparecer ou desaparecer. Pode ser uma ferramenta de linha de comando existente, um script python, código C compilável ..., mas eu devo ser capaz de integrá-lo de alguma forma ao meu script (mesmo que apenas grave algumas informações em um fifo)!

Teresa e Junior
fonte
1
Não faria sentido descobrir por que seu código antigo ativa o disco e procurar uma solução? Algo como chroot e ramdisk. Eu acho que strace -f -e trace=file wmctrl -ldeveria ser informativo.
Hauke ​​Laging
Estou usando fatracepara verificar se há ativações de disco, e isso me diz bashleituras /bin/sleepe a /usr/bin/wmctrlcada meio segundo, é por isso que estou procurando por algum programa que realmente espere eventos da janela. Estou esquecendo de algo?
Teresa e Junior
1
a leitura dessas não ativaria o disco, pois provavelmente seria armazenada em cache se fossem executadas duas vezes a cada segundo. Você montou seus sistemas de arquivos com noatime? Consulte também btracefrom blktracepara investigar as fontes de atividade do disco.
Stéphane Chazelas
1
Se você ainda não olhou para ele ainda xwininfopode ser útil, certamente cargas muito menos bibliotecas compartilhadas do que wmctrl e opera em um nível mais próximo X. nua
msw
1
@msw Estou tentando consertar o unfixable, que é um recurso de gravação automática para o Google Earth (fechado origem e relatar bugs é um desperdício de tempo)
Teresa e Junior

Respostas:

4

Isso deve fornecer todas as atividades do sistema de arquivos (OK: mais. O que eu esqueci? Sockets?) Que incluem gravações:

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

Com essas informações, um ambiente chroot funcional pode ser criado no tmpfs (como uma ação de último recurso; talvez links simbólicos para o tmpfs sejam suficientes). Se o programa for iniciado em um chroot de RAM, ele não poderá ativar o disco diretamente. Nenhuma gravação na hierarquia do sistema de arquivos é gravada no disco.

Hauke ​​Laging
fonte
Eu acredito que há momentos em que a leitura de um arquivo, pelo menos pela primeira vez, também desperta o disco, não é? Eu estou querendo saber se blktraceseria a ferramenta certa para isso, mas isso exigiria um kernel compilação # CONFIG_BLK_DEV_IO_TRACE is not set:( Isso está fora do âmbito desta questão, embora Obrigado.!
Teresa e Junior
1
@TeresaeJunior Claro, mas quem consideraria isso um problema? É sobre manter o script em execução o tempo todo, não sobre iniciá-lo. E você pode criar os tmpfs a partir de boot.local/ rc.localpara não ter acesso ao disco, mesmo que inicie o script posteriormente. Eu apenas dei uma olhada blktrace(não sabia disso antes). Isso é tão terrível que eu me pergunto se vou conseguir dormir esta noite ...
Hauke Laging
Sim, eu realmente não deveria mais me preocupar com isso, você está certo novamente. Mas acho que também vai perder esta noite de sono compilar o kernel, já que eu quiser conferir tudo o que pode ser acordar constantemente o disco, não só este hack Google Earth especial :)
Teresa e Junior
6

Pode ser mais simples e mais confiável confiar no seu gerenciador de janelas ou no X11 para lidar com isso escrevendo um aplicativo X11 "real".

O que você deseja do shell é algo que se registra no gerenciador de janelas e aguarda o tipo de evento desejado antes de retornar ao shell ... é muito mais fácil carregar se você puder evitar um loop dentro do shell. (Suas until xdotool...causas são carregadas porque não há atraso (suspensão) dentro do loop.)

Ah ... aparentemente xdotoolesse recurso foi adicionado há mais de um ano --sync. Isso não está disponível na minha distribuição atual do Linux (Debian Squeeze), então não a testei.

O desenvolvedor do xdotool que responde a uma pergunta semelhante à sua: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ

Carl Cravens
fonte
Sim, exatamente, -syncdeveria fazer o que eu quero, mas ele precisa whileporque, eventualmente, trava antes que a janela apareça e desperdiça muita CPU. Na verdade, eu compilei a xdotoolpartir da fonte porque a do Debian era incrivelmente lenta para digitar. Escrever um aplicativo que interage diretamente com o X está realmente além de mim. Obrigado!
Teresa e Junior