Eu gostaria de executar um comando como
notify-send 'a'
se minha máquina Linux estiver inativa por 5 minutos.
Por ocioso, quero dizer a mesma coisa que um protetor de tela que é ativado usaria para definir "ocioso".
Eu gostaria de executar um comando como
notify-send 'a'
se minha máquina Linux estiver inativa por 5 minutos.
Por ocioso, quero dizer a mesma coisa que um protetor de tela que é ativado usaria para definir "ocioso".
Respostas:
Eu uso um programa chamado xprintidle
para descobrir o tempo ocioso do X, que eu acho fortemente que usa a mesma fonte de dados que os protetores de tela. xprintidle
realmente não parece mais ter um upstream, mas o pacote Debian está vivo e bem.
É uma aplicação muito simples: retorna a quantidade de milissegundos desde a última interação do X:
$ sleep 1 && xprintidle
940
$ sleep 5 && xprintidle
4916
$ sleep 10 && xprintidle
9932
(nota: devido ao sistema subjacente, ele fornecerá consistentemente um valor em ms ligeiramente inferior ao tempo ocioso "real").
Você pode usar isso para criar um script que execute uma determinada sequência após cinco minutos de tempo ocioso via, por exemplo:
#!/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
O deslocamento de 100 ms deve-se à peculiaridade observada anteriormente, que xprintidle
sempre retornará um tempo um pouco menor que o tempo ocioso "real" quando executado dessa maneira. Ele funcionará sem esse deslocamento e será mais preciso até um décimo de segundo, mas disparará a xprintidle
verificação freneticamente durante os últimos milissegundos antes do final do intervalo. Não é um porco da performance, mas acho isso deselegante.
Eu tenho usado uma abordagem semelhante em um script Perl (um plugin irssi) há algum tempo, mas o acima foi escrito e não foi realmente testado, exceto por algumas tentativas durante a gravação.
Tente executá-lo em um terminal no X. Eu recomendo definir o tempo limite para, por exemplo, 5000 ms para testes e adicionar set -x
diretamente abaixo #!/bin/sh
para obter uma saída informativa e ver como funciona.
Eu uso xssstate
para esses fins. Está disponível no suckless-tools
pacote no Debian ou Ubuntu , ou upstream .
Então você pode usar o seguinte script de 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
Aqui está um aplicativo C que eu achei que você pode compilar.
$ 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);
}
}
Ele precisa de algumas bibliotecas para construir. No meu sistema Fedora 19, eu precisava das seguintes bibliotecas:
$ 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
Uma vez que estes foram instalados, eu compilei o acima descrito assim:
$ gcc xidle.c -o xidle -lX11 -lXext -lXss
Você pode ver que é capaz de relatar o número de segundos que o X está detectando como tempo ocioso executando-o da seguinte maneira:
$ 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 esse executável, você pode montar um script que pode fazer algo assim, monitorando o tempo ocioso relatado por 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
O exemplo acima mostra still < 5
até 5 segundos de tempo ocioso, ponto em que ele começa a dizer now > 5
, o que significa que mais de 5 segundos se passaram.
NOTA: Você pode incorporar o seu notify-send 'a'
no exemplo acima.
As portas bsd (coleção de pacotes) têm um programa que pode fazer isso:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
está disponível, por exemplo, aqui:
http://distcache.freebsd.org/local- distfiles / romance / xidle-26052015.tar.bz2
construir como:
# apt-get install libxss-dev # for include/X11/extensions/scrnsaver.h
# gcc -o /usr/local/bin/xidle xidle.c -lX11 -lXss
observe que o programa-precisa conter o caminho completo para o binário, como é passado para execv ().
$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"