Виконайте команду, коли система не працює та коли знову активна


15

Я хочу запустити команду, коли користувач стає неактивним (система не працює). Наприклад:

echo "You started to be inactive."

Крім того, коли користувач знову стає активним (система вже не працює):

echo "You started to be active, again."

Мені потрібен сценарій оболонки, який це зробить. Чи можливо це без таймера / інтервалу? Можливо, якісь системні події?


2
Чи можете ви трохи детальніше розібратися в тому, чого ви насправді хочете досягти?
Нілс

3
Як ви вимірюєте неробство? Користувач переглядає фільм у режимі очікування (оскільки він не взаємодіє з комп'ютером)? Чи активний користувач, який увійшов у систему?
Жил "ТАК - перестань бути злим"

З того, що я знаю, у системі є така вбудована концепція: у режимі очікування , активності тощо. Це правильно?
Ionică Bizău

@ IonicăBizău: Не дуже. Холостий у контексті системи означав би лише те, що всі процеси сплять, тобто "чогось чекають". Хоча це може траплятися досить часто в сучасній системі і, можливо, це трапляється навіть більшу частину часу, це не залишається таким чином довгий час, оскільки завжди потрібно щось робити і якщо оновити годинник. Бездіяльність , особливо в контексті вашого запитання, є скоріше функцією користувача, ніж системою, і навіть ніж зазвичай пов'язана з конкретним сеансом.
Адаефон

@Adaephon Добре. У моїй концепції система простоює, коли користувач не робить жодних дій (переміщення миші, натискання, натискання клавіші) на комп'ютері протягом х хвилин. Система стає активною, коли користувач робить першу дію: натискає кнопку миші, переміщує її, натискає клавішу тощо. Чи можливо виявити ці активні * / * активні стани за допомогою сценарію оболонки?
Ionică Bizău

Відповіді:


17

Цей потік на форумах ArchLinux містить коротку програму C, яка запитує в xscreensaver інформацію про те, як довго користувач простоює, здається, це досить близько до ваших вимог:

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

Збережіть це як getIdle.cі компілюйте з

gcc -o getIdle getIdle.c -lXss -lX11

щоб отримати виконуваний файл getIdle. Ця програма друкує "час у режимі очікування" (користувач не рухається / клацає мишкою, не використовує клавіатуру) за мілісекунди, тому сценарій bash, який будується на цьому, може виглядати так:

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

Це все ще потребує регулярного опитування, але воно робить усе необхідне ...


Працює як належить! +1
Ionică Bizău

Ви варті більше очок!
Ionică Bizău

2
Ви можете заощадити, склавши власну програму та просто використовувати xprintidle, яка доступна у більшості дистрибутивів і робить саме те саме.
Бунт

3

TMOUT в bash припинить інтерактивний сеанс після встановленої кількості секунд. Ви можете використовувати цей механізм.

Ви міг захопити вихід, встановивши відповідну пастку (я цього не перевіряв), або використовуючи bash-logout-script (~ / .bash_logout).

Ось хороша відповідь супервізора у цьому напрямку.


Це не стосується того, як користувач виконував би команду, а не виходив із системи після $TMOUTпроходження секунд.
чепнер

Чи можете ви додати більше інформації у відповідь? Мені поки незрозуміло ...
Ionică Bizău

@chepner Я додав ще детальну інформацію до своєї відповіді.
Нілс

У будь-якому випадку це просто вимикає користувача після закінчення часу. Я не думаю, що існує спосіб перервати вихід із EXITпастки чи з пастки .bash_logout.
чепнер

3

Це не зовсім те, про що ви просили, але завжди є- batchcommand (зазвичай це спеціальне виклик -command atта використання atd-daemon).

batchдозволяє надати команду виконувати команду, яку потрібно виконати, коли середнє навантаження падає нижче певної межі (зазвичай 1,5, але це можна встановити при запуску atd). З atцим також можна кинути роботу таким чином, а не працювати в певний час; робота щойно доставленаbatch в той час, і спочатку виконуйте, коли середнє навантаження падає (наприклад, воно виконується, як тільки середнє навантаження падає менше 1,5 десь після 2:00 ранку).

На жаль, пакетна робота запуститься до кінця, вона не зупиниться, якщо комп'ютер більше не працює.

+++

Якщо ви повинні йти програмування маршрут (який він виглядає , як з інших відповідей), я думаю , що я намагаюся зробити що - щось схоже на atdабо crondдемон, які контролювали увійшли користувач і / або навантаження середнього рівня . Потім цей демон може запускати скрипти / програми з певного каталогу, а також запускати / продовжувати або зупиняти їх (за сигналами).


Якби ви це зробили та використовували .lockфайли, ви могли б легко впоратися з проблемами синхронізації.
mikeserv

2

Цей потік має пару рішень на основі виявлення діяльності клавіатури та миші. Я біжу xprintidleвід роботи з хроном, яка починається кожні кілька хвилин. Але, як вони зазначають, xprintidleце не підтримується, тому ви, можливо, захочете встановити модуль Perl і використовувати це натомість:

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

Я б застосував будь-яке рішення, опитуючи з cron, у скрипті, який виходить у верхній частині, якщо інтерфейс користувача був недостатньо непрацюючим. Звичайно, сценарію знадобиться export DISPLAY=:0.0, щоб поговорити з X11.

Пам’ятайте, що клавіатура та миша можуть бути неактивними під час перегляду фільму чи виконання важкого для процесора завдання.


1

Я не знаю, як це зробити, не опитуючи якусь статистику системи, як інші відповіді використовують заставку або таймер bash idle або працює з .bash_logout, але ось ідея перевірити використання процесора.

Це все ще передбачає опитування кожні n секунд, і якщо використання вашого процесора буде менше, ніж ви вибрали, ви можете сценаріювати все, що хочете запустити. Однак, що б ви не працювали, це може підвищити використання процесора, але ви можете використовувати приємно на своїх "речах", щоб не рахувати.

Ось тестовий скрипт, що використовує top, але ви можете використовувати mpstat замість цього, або перевірити середнє завантаження?

while true
do
idle=$(top -bn2 | grep "Cpu(s)"|tail -n 1|sed "s/.*, *\([0-9.]*\)%* id.*/\1/")
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

Це просто сценарій, який я зібрав разом, щоб перевірити читання простою зверху. Ви можете проаналізувати, /proc/statале я думаю, що він показує лише загальний час, і вам потрібно буде порівнювати результати за інтервал. Вгорі є своя проблема для мене (Linux mint 16), на першому запуску, здається, ніколи не змінювати cpustats, як ніби йому доводиться чекати, щоб розібрати / proc / stat сам, отже, top -bn2але теоретично це top -bn1має працювати.


Тьфу ... справді? Опитування статистики процесора?
Рольф

До речі, ви також можете опитувати wкоманду, яка показує час простою користувача. - До речі, я не суджу, це просто те, що я хочу виявити бездіяльність, щоб увімкнути машину спати, енергоносії, і опитування йде проти цього.
Рольф

@Rolf Звучить досить суджено ... оскільки цей коментар дійсно не додає багато, його, ймовірно, слід видалити, так? У будь-якому випадку, інші відповіді використовують час простою кількома різними способами, але як можна виявити холостий режим, не дивлячись / не запитуючи систему?
Xen2050
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.