Выполните команду, если Linux не используется в течение 5 минут

16

Я хотел бы выполнить такую ​​команду, как

 notify-send 'a'

если моя Linux машина простаивала 5 минут.

В режиме ожидания я имею в виду то же самое, что экранная заставка, которая активируется, использовалась бы для определения «ожидания».

slhck
источник
Хорошо, что вы пробовали? Что сказал гугл? Вы пытались выяснить, как заставка обнаруживает это? Пожалуйста, уделите время поиску, прежде чем отправлять вопросы здесь, и прочитайте, как задать хороший вопрос .
тердон
Я только нашел программу, xautolockно примеров нет

Ответы:

20

Я использую программу xprintidleдля определения времени простоя X, которая, я думаю, использует тот же источник данных, что и заставки. xprintidleкажется, на самом деле больше нет апстрима, но пакет Debian жив и здоров.

Это очень простое приложение: оно возвращает количество миллисекунд с момента последнего взаимодействия X:

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

(примечание: из-за базовой системы она будет постоянно давать значение в мс, немного меньшее, чем «фактическое» время простоя).

Вы можете использовать это, чтобы создать скрипт, который запускает определенную последовательность после пяти минут простоя, например:

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

Смещение в 100 мс происходит из-за ранее отмеченной причуды, xprintidleкоторая всегда будет возвращать время, немного меньшее, чем «фактическое» время простоя, когда выполняется так. Он будет работать без этого смещения, а затем будет более точным с точностью до одной десятой секунды, но он будет запускать xprintidleпроверку неистово в течение последних миллисекунд до окончания интервала. Ни в коем случае не свинья, но я бы посчитал это неуместным.

Я использовал подобный подход в скрипте Perl (плагин irssi) в течение достаточно долгого времени, но вышеописанное было только что написано и не было проверено, за исключением нескольких пробных прогонов во время написания.

Попробуйте это, запустив его в терминале в X. Я рекомендую установить время ожидания, например, 5000 мс для тестирования, и добавить set -xнепосредственно ниже, #!/bin/shчтобы получить информативный вывод, чтобы увидеть, как это работает.

Даниэль Андерссон
источник
5

Я использую xssstateдля таких целей. Он доступен в suckless-toolsпакете в Debian или Ubuntu , или выше .

Затем вы можете использовать следующий скрипт:

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

Вот приложение C, которое я нашел и которое вы можете скомпилировать.

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

Для сборки требуется пара библиотек. В моей системе Fedora 19 мне нужны были следующие библиотеки:

$ 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

После того, как они были установлены, я скомпилировал вышеуказанное так:

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

Вы можете видеть, что он может сообщить количество секунд, которое X определяет как простой, запустив его так:

$ 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

Используя этот исполняемый файл, вы можете собрать сценарий, который может делать что-то вроде этого, отслеживая время простоя, сообщаемое 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

Выше показано, still < 5пока не истекло 5 секунд простоя, после чего он начинает говорить now > 5, что означает, что прошло более 5 секунд.

ПРИМЕЧАНИЕ: вы можете включить свой notify-send 'a'в приведенный выше пример.

Ссылки

ОДС
источник
-1

bsd ports (сбор пакетов) имеет программу, которая может сделать это:
http://man.openbsd.org/OpenBSD-current/man1/xidle.1
она доступна, например, здесь:
http://distcache.freebsd.org/local- DISTFILES / роман / xidle-26052015.tar.bz2

построить как:

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

обратите внимание, что -program должен содержать полный путь к двоичному файлу, так как он передается в execv ().

$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"  
r00t
источник