Виконайте команду, якщо Linux не працює 5 хвилин


16

Я хотів би виконати таку команду, як

 notify-send 'a'

якщо моя машина Linux не працює 5 хвилин.

Під простоєм я маю на увазі те саме, що заставка, яка активується, використала б для визначення "простою".


Гаразд, що ви спробували? Що сказав Google? Ви намагалися з'ясувати, як заставка виявляє це? Будь-ласка, знайдіть час для пошуку, перш ніж розміщувати питання тут і читати, як правильно поставити запитання .
тердон

Я знайшов лише програму, 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 (колекція пакунків) мають програму, яка може це зробити:
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

зауважте, що -програма повинна містити повний шлях до двійкового файлу, оскільки він передається до execv ().

$ xidle -timeout 120 -program "/usr/bin/xlock -mode pyro"  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.