In einem Shell-Skript muss ich warten, bis ein Fenster mit einem String im Titel angezeigt wird, eine Aktion ausführen und dann warten, bis es verschwindet, und eine andere Aktion ausführen.
Bis gestern hatte ich diesen einfachen Code. Das Problem dabei ist, dass die Festplatte nicht in einen Energiesparmodus versetzt werden kann, während das Skript ausgeführt wird, und dies kann viele Stunden dauern:
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 ich feststellte, dass der erwähnte Code die Festplatte wahnsinnig weckte, ging ich die Dokumentation einiger Befehlszeilentools durch und beschloss xdotool
, auf das Erscheinen des Fensters zu warten und xprop
herauszufinden, wann das Fenster verschwunden ist:
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
Jetzt habe ich zwei neue Probleme mit dem obigen Code:
xdotool
Es stürzt nicht nur ab und liefert seltsame Ergebnisse, wie ich bereits zuvor umgangen habe, sondern es saugt auch etwa 15% der CPU an, während es darauf wartet, dass das Fenster angezeigt wird. Das bedeutet, dass ich einfachen Code losgeworden bin, der die Festplatte aufweckt, um Code zu schreiben, der die CPU stundenlang verschwendet, und ich wollte in erster Linie Strom sparen.xprop -spy
benachrichtigt mich jedes Mal, wenn ich den Fokus ändere (den ich umgangen habe$_line
) oder Fenster erstelle und zerstöre. Dadurch wird die Festplatte häufiger geweckt als bei xdotool.
Ich suche ein einfaches Programm, das nur darauf wartet, dass das Fenster mit dem Titel $string
erscheint oder verschwindet. Es kann ein vorhandenes Befehlszeilentool, ein Python-Skript, kompilierbarer C-Code sein ..., aber ich sollte es irgendwie in mein Skript integrieren können (selbst wenn es nur einige Informationen in ein Fifo schreibt)!
strace -f -e trace=file wmctrl -l
sollte informativ sein.fatrace
für Disk Wakeups zu überprüfen, und es sagt mir ,bash
liest/bin/sleep
und/usr/bin/wmctrl
jede halbe Sekunde, deshalb habe ich für einige Programm bin auf der Suche , die tatsächlich für Fenster Ereignisse warten werde. Vermisse ich etwasbtrace
vonblktrace
, um die Quellen der Festplattenaktivität zu untersuchen.xwininfo
könnte es sicherlich weit weniger gemeinsam genutzte Bibliotheken als wmctrl laden und auf einer Ebene arbeiten, die näher an Bare X liegt.Antworten:
Dies sollte Ihnen alle (OK: die meisten. Was habe ich vergessen? Sockets?) Dateisystemaktivitäten geben, die Schreibvorgänge umfassen:
Mit diesen Informationen kann eine funktionierende Chroot-Umgebung in tmpfs erstellt werden (als letzte Möglichkeit; möglicherweise reichen Symlinks zu tmpfs aus). Wenn das Programm in einem RAM-Chroot gestartet wird, hat es keine Chance, die Festplatte direkt zu aktivieren. Kein Schreiben in die Dateisystemhierarchie wird jemals auf die Festplatte geschrieben.
quelle
blktrace
das das richtige Werkzeug dafür wäre, aber es würde eine Kernel-Kompilierung erfordern# CONFIG_BLK_DEV_IO_TRACE is not set
:( Das geht jedoch über den Rahmen dieser Frage hinaus. Danke!boot.local
/ erstellen,rc.local
sodass Sie keinen Festplattenzugriff haben, selbst wenn Sie das Skript später starten. Ich habe es mir nur angesehenblktrace
(wusste das vorher nicht). Das ist so schrecklich, dass ich mich frage, ob ich heute Nacht einschlafen werde ...Es ist möglicherweise einfacher und zuverlässiger, sich darauf zu verlassen, dass Ihr Fenstermanager oder X11 dies erledigt, indem Sie eine "echte" X11-Anwendung schreiben.
Was Sie von der Shell erwarten, ist etwas, das sich beim Fenstermanager registriert und auf einen gewünschten Ereignistyp wartet, bevor Sie zur Shell zurückkehren. Es ist viel lastfreundlicher, wenn Sie eine Schleife innerhalb der Shell vermeiden können. (Ihre
until xdotool...
Ursachen laden, weil es keine Verzögerung (Schlaf) innerhalb der Schleife gibt.)Ah ... hatte anscheinend
xdotool
diese Funktion vor über einem Jahr hinzugefügt--sync
. Das ist in meiner aktuellen Linux-Distribution (Debian Squeeze) nicht verfügbar, daher habe ich es nicht ausprobiert.Der xdotool-Entwickler beantwortet eine ähnliche Frage wie Sie: https://groups.google.com/d/msg/xdotool-users/7zfKTtyWm0Q/DM6TSOBUWZMJ
quelle
-sync
sollte tun, was ich will, aber es braucht das,while
weil es irgendwann abstürzt, bevor das Fenster erscheint, und zu viel CPU verschwendet. Ich habe tatsächlichxdotool
aus dem Quellcode kompiliert, weil der von Debian unglaublich langsam zu tippen war. Das Schreiben einer Anwendung, die direkt mit X interagiert, ist mir eigentlich ein Rätsel. Trotzdem danke!