Attendi che una finestra X appaia / scompaia (in modo sano)


11

All'interno di uno script di shell, devo aspettare che appaia una finestra con una stringa sul titolo, fare qualche azione, quindi aspettare che scompaia e fare qualche altra azione.

Fino a ieri avevo questo semplice codice. Il problema è che il disco non può essere messo in uno stato di risparmio energetico mentre lo script viene lasciato in esecuzione e può durare per molte ore:

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

Da quando ho deciso che il codice citato stava riattivando follemente il disco, ho esaminato la documentazione di alcuni strumenti della riga di comando e ho deciso xdotooldi attendere che appaia la finestra e xpropdi capire quando la finestra è svanita:

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

Ora ho due nuovi problemi con il codice sopra:

  • xdotoolnon solo si arresta in modo anomalo e dà risultati strani, come ho già aggirato in precedenza, ma succhia anche circa il 15% della CPU mentre rimane in attesa che appaia la finestra. Ciò significa che mi sono sbarazzato del semplice codice che riattiva il disco, di scrivere codice che è rimasto sprecando la CPU per ore e la mia intenzione era di risparmiare energia in primo luogo.
  • xprop -spymi avviserà ogni volta che cambio focus (su cui ho risolto il problema $_line) o creo e distruggo windows. Ciò riattiva il disco più frequentemente di xdotool.

Sto cercando un semplice programma in attesa $stringche appaia o scompaia la finestra con il titolo . Può essere uno strumento a riga di comando esistente, uno script Python, un codice C compilabile ..., ma dovrei essere in grado di integrarlo in qualche modo nel mio script (anche se scrive solo alcune informazioni su un FIFO)!


1
Non avrebbe senso scoprire perché il tuo vecchio codice riattiva il disco e cercare una soluzione? Qualcosa come chroot e ramdisk. Immagino che strace -f -e trace=file wmctrl -ldovrebbe essere informativo.
Hauke ​​Laging

Sto usando fatraceper verificare la riattivazione del disco, e mi dice bashletture /bin/sleepe /usr/bin/wmctrlogni mezzo secondo, è per questo che sto cercando un programma che effettivamente aspetterà gli eventi della finestra. Mi sto perdendo qualcosa?
Teresa e Junior

1
la lettura di questi non riattiva il disco in quanto verrebbero probabilmente memorizzati nella cache se fossero eseguiti due volte al secondo. Hai montato i tuoi filesystem con noatime? Vedi anche btraceda blktraceper esaminare le fonti di attività del disco.
Stéphane Chazelas,

1
Se non l'hai ancora visto xwininfopotrebbe essere utile, carica sicuramente molte meno librerie condivise rispetto a wmctrl e funziona a un livello più vicino a X nudo.
msw

1
@msw Sto cercando di risolvere il problema non risolvibile, che è una funzione di salvataggio automatico per Google Earth (l'approvvigionamento chiuso e la segnalazione di bug è una perdita di tempo)
Teresa e Junior

Risposte:


4

Questo dovrebbe darti tutte le attività del file system (OK: la maggior parte. Cosa ho dimenticato? Sockets?) Che includono le scritture:

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

Con queste informazioni è possibile creare un ambiente chroot funzionante in tmpfs (come azione di ultima istanza; forse sono sufficienti collegamenti simbolici a tmpfs). Se il programma viene avviato in un chroot RAM, non è possibile riattivare direttamente il disco. Nessuna scrittura nella sua gerarchia di file system viene mai scritta su disco.


Credo che ci siano momenti in cui la lettura di un file, almeno per la prima volta, riattiverà anche il disco, no? Mi chiedo se blktracesarebbe lo strumento giusto per questo, ma richiederebbe una compilazione del kernel # CONFIG_BLK_DEV_IO_TRACE is not set:( Questo va oltre lo scopo di questa domanda. Grazie!
Teresa e Junior

1
@TeresaeJunior Sicuro ma chi lo considererebbe un problema? Si tratta di mantenere lo script sempre in esecuzione, non di avviarlo. E puoi creare i tmpfs da boot.local/ in rc.localmodo da non avere accesso al disco anche se avvii lo script in un secondo momento. Ho appena dato un'occhiata blktrace(non lo sapevo prima). È così terribile che mi chiedo se
riuscirò

Sì, non dovrei più preoccuparmi di questo, hai di nuovo ragione. Ma penso che perderò anche questa notte di sonno compilando il kernel, dal momento che voglio controllare tutto ciò che potrebbe svegliare costantemente il disco, non solo questo particolare hack di Google Earth :)
Teresa e Junior

6

Potrebbe essere più semplice e affidabile affidarsi al proprio gestore di finestre o X11 per gestirlo scrivendo un'applicazione "reale" X11.

Quello che vuoi dalla shell è qualcosa che si registra con il gestore delle finestre e attende il tipo di evento desiderato prima di tornare alla shell ... è molto più facile da caricare se riesci ad evitare il loop all'interno della shell. (Le tue until xdotool...cause si caricano perché non c'è alcun ritardo (sospensione) all'interno del loop.)

Ah ... a quanto pare xdotoolquesta funzionalità è stata aggiunta oltre un anno fa --sync. Questo non è disponibile nella mia attuale distribuzione Linux (Debian Squeeze), quindi non l'ho provato.

Lo sviluppatore di xdotool risponde a una domanda simile alla tua: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ


Sì, esattamente, -syncavrebbe dovuto fare quello che volevo, ma ha bisogno del whileperché alla fine si bloccherà prima che appaia la finestra e sprechi troppa CPU. In realtà ho compilato xdotooldal sorgente perché quello di Debian era incredibilmente lento da digitare. Scrivere un'applicazione che interagisce direttamente con X è in realtà al di là di me. Grazie comunque!
Teresa e Junior,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.