Esegui un comando se Linux è inattivo per 5 minuti


16

Vorrei eseguire un comando come

 notify-send 'a'

se la mia macchina Linux è rimasta inattiva per 5 minuti.

Per inattivo, intendo la stessa cosa che uno screen saver che viene attivato userebbe per definire "inattivo".


OK, cosa hai provato? Cosa ha detto google? Hai provato a scoprire come lo screensaver rileva questo? Ti preghiamo di dedicare del tempo alla ricerca prima di pubblicare qui le domande e leggere Come fare una buona domanda .
terdon,

Ho trovato solo un programma xautolockma non ci sono esempi

Risposte:


20

Uso un programma chiamato xprintidleper scoprire il tempo di inattività X, che suppongo fortemente utilizzi la stessa fonte di dati degli screensaver. xprintidlenon sembra più avere un upstream, ma il pacchetto Debian è vivo e vegeto.

È un'applicazione molto semplice: restituisce la quantità di millisecondi dall'ultima interazione X:

$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932

(nota: a causa del sistema sottostante, fornirà costantemente un valore in ms leggermente inferiore al tempo di inattività "effettivo").

Puoi usarlo per creare uno script che esegue una determinata sequenza dopo cinque minuti di inattività tramite ad esempio:

#!/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

L'offset di 100 ms è dovuto alla stranezza notata in precedenza xprintidle restituirà sempre un tempo leggermente inferiore al tempo di inattività "effettivo" quando eseguito in questo modo. Funzionerà senza questo offset e sarà quindi più preciso di un decimo di secondo, ma attiverà il xprintidlecontrollo freneticamente negli ultimi millisecondi prima della fine di un intervallo. Non un maiale da prestazione in alcun modo, ma lo troverei inelegante.

Ho usato un approccio simile in uno script Perl (un plug-in irssi) per un po 'di tempo, ma quanto sopra è stato appena scritto e non è stato testato se non per alcune prove durante la scrittura.

Provalo eseguendolo in un terminale all'interno di X. Ti consiglio di impostare il timeout su ad es. 5000 ms per il test e di aggiungere set -xdirettamente sotto #!/bin/shper ottenere un output informativo per vedere come funziona.


5

Uso xssstateper tali scopi. È disponibile in suckless-toolspacchetto in Debian o Ubuntu o upstream .

Quindi è possibile utilizzare il seguente script shell:

#!/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

1

Ecco un'applicazione C che ho trovato che puoi compilare.

$ 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);
    }
}

Ha bisogno di un paio di librerie da compilare. Sul mio sistema Fedora 19 avevo bisogno delle seguenti librerie:

$ 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

Una volta installati questi ho compilato quanto sopra in questo modo:

$ gcc xidle.c -o xidle -lX11 -lXext -lXss

Puoi vedere che è in grado di segnalare il numero di secondi che X sta rilevando come tempo di inattività eseguendolo in questo modo:

$ 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

Usando questo eseguibile potresti mettere insieme uno script che può fare qualcosa del genere, monitorando il tempo di inattività riportato da 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

Quanto sopra mostra still < 5fino a quando sono trascorsi 5 secondi di inattività, a quel punto inizia a dire now > 5, il che significa che sono trascorsi 5+ secondi.

NOTA: è possibile incorporare notify-send 'a'l'esempio sopra riportato.

Riferimenti


-1

bsd porte (collezione di pacchetti) ha un programma che può fare questo:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
è disponibile ad es. qui:
http://distcache.freebsd.org/local- distfiles / romanzo / xidle-26052015.tar.bz2

costruire come:

 # apt-get install libxss-dev # for include/X11/extensions/scrnsaver.h
 # gcc -o /usr/local/bin/xidle xidle.c -lX11 -lXss

si noti che il programma deve contenere l'intero percorso del file binario, poiché viene passato a execv ().

$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"  
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.