Как скрипт может обнаружить время простоя пользователя?

Я хочу проверить внутри bash-скрипта, как долго пользователь X-сессии простаивает.

Сам пользователь не должен использовать bash, а просто X. Если пользователь, например, просто переместил мышь, хорошим ответом будет "простоя в течение 0 секунд". Если он не коснулся компьютера в течение 5 минут, хорошим ответом было бы "бездействовать в течение 300 секунд"

Причина, по которой вы не можете сразу использовать xautolock, заключается в том, чтобы иметь возможность реализовывать некоторые сложные действия. Например, если пользователь простаивает в течение 10 минут, попробуйте приостановить, если он простаивает более 5 минут, отключение (я знаю, это звучит странно, но приостановка не всегда работает здесь...)

4 ответа

Решение

Просто нашел простой способ сделать это.

Существует программа под названием xprintidle, которая делает свое дело

получить простой (в миллисекундах) так же просто, как

xprintidle

и установить

apt-get install xprintidle

Для системных администраторов это также работает удаленно

Из сеанса SSH:

export DISPLAY=:0 && sudo -u john xprintidle

где john - пользователь, вошедший в сеанс X на удаленной машине.

Использование ответа josinalvo может сработать для некоторых, но для меня это не сработало так хорошо, поскольку некоторые программы, похоже, регулярно сбрасывают таймер , на котором xprintidleполагается, неожиданно. Кроме того, я также не хотел бы, чтобы полноэкранное приложение сбрасывало таймер простоя, по крайней мере, не в моем случае использования.

Поэтому я собрал свое собственное решение в сценарии оболочки, который не зависит от расширения X11 Screen Saver. Вместо этого он сбрасывает весь пользовательский ввод, такой как движение мыши и нажатия клавиш, используя xinput test-xi2 --rootза одну секунду, а затем сравнивает его с дампом за последнюю секунду. Если они совпадают, переменная увеличивается на 1 и сбрасывается в другом случае. Это зациклено, и когда переменная $tпереступает порог в $idletime, печатается, что пользователь простаивает.

      idleloop() {
    touch /tmp/.{,last_}input
    cmd='stat --printf="%s"'
    idletime=120
    a=2
    t=0
    while true
    do
        timeout 1 xinput test-xi2 --root > /tmp/.input
        
        if [[ `eval $cmd /tmp/.input` == `eval $cmd /tmp/.last_input` ]]
        then
            let t++ # increases $t by 1
        else
            t=0     # resets $t
        fi

        mv /tmp/.{,last_}input -f

        if [ $t -ge $idletime ] && [[ $a == "2" ]]
        then
            echo "user has gone idle"
            a=1
        fi
        if [ $t -lt $idletime ] && [[ $a == "1" ]]
        then
            echo "user has come back from idle"
            a=2
        fi
    done
}

idleloop

Не стесняйтесь оставлять любые предложения.

Ответ отсюда:

В баш

w | tr -s " " | cut -d" " -f1,5 | tail -n+3

дает вам пару username/idletime для каждой оболочки. Таким образом, в основном вы можете получить информацию о простое через команду w

Вот полный сценарий bash, который определяет, простаивает ли пользователь/система в течение 5 или более секунд, и записывает данные в файл. С помощью другого сценария bash или Python мы можем выполнить дополнительный анализ этого текстового файла. Очевидно, мы можем изменить эти значения (idletime_threshold) в соответствии с требованиями.

#!/бин/баш
# обнаружить-user-idle-busy-time-with-dbus.sh

idletime_threshold=5000 # в миллисекундах
# idletime_threshold=300000 # в миллисекундах
а=2
вывод = система-idle-busy.txt
петля бездействия () {
    пока правда
    делать
        спать 1 # секунды
        now=`date "+%Y-%m-%d %H:%M:%S"`
        get_idle_time=`dbus-send --print-reply --dest=org.gnome.Mutter.IdleMonitor /org/gnome/Mutter/IdleMonitor/Core org.gnome.Mutter.IdleMonitor.GetIdletime`
        idle_time=$(echo $get_idle_time | awk '{print $NF}')
        #echo "${idle_time}" # миллисекунд

        если [ $idle_time -ge $idletime_threshold ] && [[ $a == "2" ]]
        тогда
            echo "бездействует: ${сейчас}" | тройник -a $ вывод  
            а=1
        фи

        если [ $idle_time -lt $idletime_threshold ] && [[ $a == "1" ]]
        тогда
            echo "занят: ${сейчас}" | тройник -a $ вывод  
            а=2
        фи
    Выполнено
}
петля бездействия

выход:

u-20:~/Downloads$ tailc -f system-idle-busy.txt
простоя : 2022-09-15 14:20:00
занят : 2022-09-15 14:20:02
простоя : 2022-09-15 14:20:25
занят : 2022-09-15 14:20:59
простоя : 2022-09-15 14:23:48
Другие вопросы по тегам