Executa um comando quando o sistema está inativo e quando está ativo novamente

14

Eu quero executar um comando quando o usuário ficar inativo (o sistema está ocioso). Por exemplo:

echo "You started to be inactive."

Além disso, quando o usuário se torna ativo novamente (o sistema não está mais ocioso):

echo "You started to be active, again."

Eu preciso de um script de shell que faça isso. Isso é possível sem um temporizador / intervalo? Talvez alguns eventos do sistema?

    
por Ionică Bizău 22.03.2014 / 20:49

5 respostas

16

Este tópico nos fóruns do ArchLinux contém um pequeno programa em C que consulta o xscreensaver por quanto tempo o usuário ficou ocioso, parece ser bem próximo dos seus requisitos:

#include <X11/extensions/scrnsaver.h>
#include <stdio.h>

int main(void) {
    Display *dpy = XOpenDisplay(NULL);

    if (!dpy) {
        return(1);
    }

    XScreenSaverInfo *info = XScreenSaverAllocInfo();
    XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info);
    printf("%u\n", info->idle);

      return(0);
}

Salvar como getIdle.c e compilar com

gcc -o getIdle getIdle.c -lXss -lX11

para obter um arquivo executável getIdle . Este programa imprime o "tempo ocioso" (o usuário não se move / clica com o mouse, não usa o teclado) em milissegundos, portanto, um script bash que se baseia nisso poderia ter a seguinte aparência:

#!/bin/bash

idle=false
idleAfter=3000     # consider idle after 3000 ms

while true; do
  idleTimeMillis=$(./getIdle)
  echo $idleTimeMillis  # just for debug purposes.
  if [[ $idle = false && $idleTimeMillis -gt $idleAfter ]] ; then
    echo "start idle"   # or whatever command(s) you want to run...
    idle=true
  fi

  if [[ $idle = true && $idleTimeMillis -lt $idleAfter ]] ; then
    echo "end idle"     # same here.
    idle=false
  fi
  sleep 1      # polling interval

done

Isso ainda precisa de pesquisas regulares, mas faz tudo que você precisa ...

    
por 02.04.2014 / 21:23
3

O TMOUT no bash encerrará uma sessão interativa após o número de segundos definido. Você pode usar esse mecanismo.

Você pode capturar o logout definindo uma armadilha correspondente (eu não testei isso) ou usando os scripts bash-logout (~ / .bash_logout).

Aqui está uma boa resposta de superusuário para essa direção.

    
por 22.03.2014 / 22:22
3

Isso não é exatamente o que você pediu, mas sempre há o batch -command (geralmente uma invocação especial do at -command e usando o atd -daemon).

batch permite que você execute um comando para ser executado quando a média da carga cair abaixo de um determinado limite (geralmente 1,5, mas isso pode ser definido ao iniciar o atd ). Com at também é possível indicar um trabalho de tal forma que em vez de ser executado em um determinado momento; o trabalho é entregue a batch nesse momento e é executado pela primeira vez quando a média de carga cai (por exemplo, ele é executado assim que a média da carga cai abaixo de 1,5 após as 2:00 da manhã).

Infelizmente, um trabalho em lote será executado no final, não será interrompido se o computador não estiver mais ocioso.

+++

Se você tiver que seguir a rota de programação (que parece das outras respostas), eu acho que tentaria fazer algo semelhante aos daemons atd ou crond , que monitoravam usuários conectados e / ou média de carga. Este daemon poderia então executar scripts / programas de um determinado diretório, e iniciar / continuar ou pará-los (com sinais) conforme necessário.

    
por 03.04.2014 / 15:07
2

Este tópico tem algumas soluções baseadas na detecção de teclado e mouse atividade. Eu corro xprintidle de um cron job que inicia a cada poucos minutos. Mas como eles apontam xprintidle é não-mantido, então você pode querer instalar o módulo Perl e usá-lo:

$ cpanm X11::IdleTime
...
$ sleep 10; perl -MX11::IdleTime -le 'print GetIdleTime()'
9

Eu usaria qualquer uma das soluções pesquisando pelo cron, em um script que saia da parte superior se a UI não estivesse suficientemente ociosa. É claro que o script precisaria de um export DISPLAY=:0.0 para falar com o X11.

Lembre-se de que o teclado e o mouse podem estar inativos ao assistir a um filme ou ao executar uma tarefa pesada da CPU.

    
por 16.04.2016 / 10:38
1

Não conheço uma maneira de fazer isso sem consultar algumas estatísticas do sistema, como as outras respostas usam um protetor de tela ou um temporizador ocioso do bash ou a execução de .bash_logout, mas aqui está uma ideia para verificar o uso da CPU. / p>

Isso ainda envolverá sondar a cada n segundos e, se o uso da CPU estiver abaixo da quantidade escolhida, você poderá criar scripts para o que quiser executar. No entanto, o que quer que você execute pode aumentar o uso da CPU, mas você pode usar bem o seu "material" para não contar.

Aqui está um script de teste usando top, mas você pode usar o mpstat, ou verificar as médias de carga?

while true
do
idle=$(top -bn2 | grep "Cpu(s)"|tail -n 1|sed "s/.*, *\([0-9.]*\)%* id.*//")
echo "idle is $idle"
if [[ $idle > 90 ]]
then
    echo "idle above 90%"
    echo "Do stuff now"
else
    echo "idle below 90%"
    echo "Stop doing stuff now"
fi
sleep 1
done

Isso é apenas um roteiro que eu joguei para testar lendo o ocioso do topo. Você poderia analisar /proc/stat , mas acho que só mostra o total de vezes e você precisaria comparar os resultados em um intervalo. Top tem seu próprio problema para mim (linux mint 16), na primeira execução parece nunca alterar cpustats, como se ele tivesse que esperar para analisar / proc / stat, portanto o top -bn2 mas em teoria top -bn1 deveria trabalho.

    
por 03.04.2014 / 01:47