Dans un script shell, j'ai besoin d'attendre qu'une fenêtre qui a une chaîne sur son titre apparaisse, faire une action, puis attendre qu'elle disparaisse et faire une autre action.
Jusqu'à hier, j'avais ce code simple. Le problème est que le disque ne peut pas être mis dans un état d'économie d'énergie pendant que le script est en cours d'exécution, et cela peut durer plusieurs heures:
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
Depuis que j'ai décidé que le code mentionné réveillait follement le disque, j'ai parcouru la documentation de quelques outils de ligne de commande, et j'ai décidé xdotool
d'attendre que la fenêtre apparaisse et xprop
de savoir quand la fenêtre a disparu:
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
Maintenant, j'ai deux nouveaux problèmes avec le code ci-dessus:
xdotool
non seulement se bloque et donne des résultats étranges, comme je l'ai déjà contourné, mais il aspire également environ 15% du processeur en attendant que la fenêtre apparaisse. Cela signifie donc que je me suis débarrassé du code simple qui réveille le disque, pour écrire du code qui laisse le CPU gaspiller pendant des heures, et mon intention était d'économiser de l'énergie en premier lieu.xprop -spy
m'informera chaque fois que je changerai de focus (que j'ai contourné$_line
) ou créer et détruire des fenêtres. Cela réveille le disque plus fréquemment que xdotool.
Je recherche un programme simple qui n'attend que la fenêtre avec le titre $string
pour apparaître ou disparaître. Cela peut être un outil de ligne de commande existant, un script python, du code C compilable ..., mais je devrais être capable de l'intégrer d'une manière ou d'une autre à mon script (même s'il écrit juste des informations dans un fifo)!
strace -f -e trace=file wmctrl -l
devrait être informatif.fatrace
pour vérifier les réveils de disque, et cela m'indique lesbash
lectures/bin/sleep
et/usr/bin/wmctrl
toutes les demi-secondes, c'est pourquoi je recherche un programme qui attendra réellement les événements de fenêtre. Suis-je en train de manquer quelque chose?btrace
deblktrace
pour rechercher les sources d'activité du disque.xwininfo
pourrait être utile, il charge certainement beaucoup moins de bibliothèques partagées que wmctrl et fonctionne à un niveau plus proche de X.Réponses:
Cela devrait vous donner toutes les activités du système de fichiers (OK: la plupart. Qu'est-ce que j'ai oublié? Sockets?) Qui incluent les écritures:
Avec ces informations, un environnement de travail chroot peut être créé dans tmpfs (comme une action de dernier recours; peut-être que les liens symboliques vers tmpfs suffisent). Si le programme est démarré dans un chroot RAM, il n'a pas la possibilité de réveiller directement le disque. Aucune écriture dans sa hiérarchie de système de fichiers n'est jamais écrite sur le disque.
la source
blktrace
serait le bon outil pour cela, mais cela nécessiterait une compilation du noyau# CONFIG_BLK_DEV_IO_TRACE is not set
:( Cela dépasse cependant la portée de cette question. Merci!boot.local
/rc.local
afin que vous n'ayez pas accès au disque même si vous démarrez le script plus tard. J'ai juste regardéblktrace
(je ne le savais pas avant). C'est tellement terrible que je me demande si je vais pouvoir dormir ce soir ...Il pourrait être plus simple et plus fiable de compter sur votre gestionnaire de fenêtres ou X11 pour gérer cela en écrivant une "vraie" application X11.
Ce que vous voulez du shell est quelque chose qui s'enregistre auprès du gestionnaire de fenêtres et attend le type d'événement souhaité avant de retourner au shell ... c'est beaucoup plus convivial si vous pouvez éviter de boucler à l'intérieur du shell. (Votre
until xdotool...
cause la charge car il n'y a pas de retard (sommeil) à l'intérieur de la boucle.)Ah ... apparemment,
xdotool
cette fonctionnalité a été ajoutée il y a plus d'un an--sync
. Ce n'est pas disponible dans ma distribution Linux actuelle (Debian Squeeze), donc je ne l'ai pas essayé.Le développeur xdotool répondant à une question similaire à la vôtre: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ
la source
-sync
était censé faire ce que je veux, mais il en a besoinwhile
car il finira par planter avant que la fenêtre n'apparaisse et gaspille trop de CPU. J'ai en fait compilé àxdotool
partir des sources car celui de Debian était incroyablement lent à taper. Écrire une application qui interagit directement avec X me dépasse en fait. Merci quand même!