Je voudrais exécuter une commande telle que
notify-send 'a'
si ma machine Linux est inactive depuis 5 minutes.
Par inactif, je veux dire la même chose qu'un économiseur d'écran qui s'active utiliserait pour définir "inactif".
Je voudrais exécuter une commande telle que
notify-send 'a'
si ma machine Linux est inactive depuis 5 minutes.
Par inactif, je veux dire la même chose qu'un économiseur d'écran qui s'active utiliserait pour définir "inactif".
Réponses:
J'utilise un programme appelé xprintidle
pour connaître le temps d'inactivité X, qui, je suppose, utilise la même source de données que les économiseurs d'écran. xprintidle
ne semble plus vraiment avoir d'amont, mais le paquet Debian est bel et bien vivant.
C'est une application très simple: elle retourne le nombre de millisecondes depuis la dernière interaction X:
$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932
(Remarque: en raison du système sous-jacent, il donnera systématiquement une valeur en ms légèrement inférieure au temps d'inactivité "réel").
Vous pouvez l'utiliser pour créer un script qui exécute une certaine séquence après cinq minutes d'inactivité via par exemple:
#!/bin/sh
# Wanted trigger timeout in milliseconds.
IDLE_TIME=$((5*60*1000))
# Sequence to execute when timeout triggers.
trigger_cmd() {
echo "Triggered action $(date)"
}
sleep_time=$IDLE_TIME
triggered=false
# ceil() instead of floor()
while sleep $(((sleep_time+999)/1000)); do
idle=$(xprintidle)
if [ $idle -ge $IDLE_TIME ]; then
if ! $triggered; then
trigger_cmd
triggered=true
sleep_time=$IDLE_TIME
fi
else
triggered=false
# Give 100 ms buffer to avoid frantic loops shortly before triggers.
sleep_time=$((IDLE_TIME-idle+100))
fi
done
Le décalage de 100 ms est dû à la bizarrerie notée précédemment qui xprintidle
retournera toujours un temps légèrement inférieur au temps d'inactivité "réel" lorsqu'il est exécuté comme ceci. Il fonctionnera sans ce décalage, et sera alors plus précis au dixième de seconde, mais il déclenchera le xprintidle
contrôle frénétiquement pendant les dernières millisecondes avant la fin d'un intervalle. Pas un porc de performance en aucune façon, mais je trouverais cela inélégant.
J'ai utilisé une approche similaire dans un script Perl (un plugin irssi) pendant un certain temps, mais ce qui précède vient d'être écrit et n'a pas vraiment été testé, à l'exception de quelques essais pendant l'écriture.
Essayez-le en l'exécutant dans un terminal au sein de X. Je recommande de définir le délai d'expiration à par exemple 5000 ms pour les tests, et en ajoutant set -x
directement ci-dessous #!/bin/sh
pour obtenir une sortie informative pour voir comment cela fonctionne.
J'utilise xssstate
à de telles fins. Il est disponible en suckless-tools
package dans Debian ou Ubuntu , ou en amont .
Ensuite, vous pouvez utiliser le script shell suivant:
#!/bin/sh
if [ $# -lt 2 ];
then
printf "usage: %s minutes command\n" "$(basename $0)" 2>&1
exit 1
fi
timeout=$(($1*60*1000))
shift
cmd="$@"
triggered=false
while true
do
tosleep=$(((timeout - $(xssstate -i)) / 1000))
if [ $tosleep -le 0 ];
then
$triggered || $cmd
triggered=true
else
triggered=false
sleep $tosleep
fi
done
Voici une application C que j'ai trouvée que vous pouvez compiler.
$ more xidle.c
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/scrnsaver.h>
/* Report amount of X server idle time. */
/* Build with- */
/* cc xidle.c -o xidle -lX11 -lXext -lXss */
int main(int argc, char *argv[])
{
Display *display;
int event_base, error_base;
XScreenSaverInfo info;
float seconds;
display = XOpenDisplay("");
if (XScreenSaverQueryExtension(display, &event_base, &error_base)) {
XScreenSaverQueryInfo(display, DefaultRootWindow(display), &info);
seconds = (float)info.idle/1000.0f;
printf("%f\n",seconds);
return(0);
}
else {
fprintf(stderr,"Error: XScreenSaver Extension not present\n");
return(1);
}
}
Il a besoin de quelques bibliothèques pour se construire. Sur mon système Fedora 19, j'avais besoin des bibliothèques suivantes:
$ rpm -qf /lib64/libX11.so.6 /lib64/libXext.so.6 /lib64/libXss.so.1
libX11-1.6.0-1.fc19.x86_64
libXext-1.3.2-1.fc19.x86_64
libXScrnSaver-1.2.2-5.fc19.x86_64
Une fois ceux-ci installés, j'ai compilé ce qui précède comme suit:
$ gcc xidle.c -o xidle -lX11 -lXext -lXss
Vous pouvez voir qu'il est capable de signaler le nombre de secondes que X détecte comme temps d'inactivité en l'exécutant comme suit:
$ while [ 1 ]; do ./xidle ; sleep 2;done
0.005000
1.948000
3.954000
5.959000
7.965000
0.073000 <--- moved the mouse here which resets it
0.035000
En utilisant cet exécutable, vous pouvez créer un script qui peut faire quelque chose comme ça, en surveillant le temps d'inactivité signalé par xidle
.
$ while [ 1 ]; do idle=$(./xidle);
[ $( echo "$idle > 5" | bc ) -eq 0 ] && echo "still < 5" || echo "now > 5";
sleep 2;
done
still < 5
still < 5
still < 5
now > 5
now > 5
still < 5
still < 5
still < 5
Ce qui précède montre still < 5
jusqu'à ce que 5 secondes d'inactivité se soient écoulées, moment auquel il commence à dire now > 5
, ce qui signifie que plus de 5 secondes se sont écoulées.
REMARQUE: vous pouvez intégrer votre notify-send 'a'
dans l'exemple ci-dessus.
les ports bsd (collection de packages) ont un programme qui peut le faire:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
il est disponible par exemple ici:
http://distcache.freebsd.org/local- distfiles / novel / xidle-26052015.tar.bz2
construire comme:
# apt-get install libxss-dev # for include/X11/extensions/scrnsaver.h
# gcc -o /usr/local/bin/xidle xidle.c -lX11 -lXss
notez que -program doit contenir le chemin complet du binaire, car il est passé à execv ().
$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"