Запустіть сценарій на блокування / розблокування екрана


54

Я хотів би запустити екран, якщо сеанс Gnome заблокований та розблокований. Чи є спосіб я перехопити це та виконати певні дії, коли робочий стіл заблокований чи розблокований?

Відповіді:


49

Заставка Gnome випромінює деякі сигнали на dbus, коли щось відбувається.

Ось документація (з деякими прикладами).

Ви можете написати сценарії, які виконуються:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"

і це робить те, що вам потрібно в будь-який час, dbus-monitorдрукує рядок про заблокований / розблокований екран.


Ось команда bash зробити те, що потрібно:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

Просто замініть echo SCREEN_LOCKEDі echo SCREEN_UNLOCKEDтим, що вам потрібно.


Привіт @peoro, тому я думаю, що ти можеш розблокувати або заблокувати екран / сеанс gnome з сценарію програми, варто зробити кілька ssh трюків щодо цього ;-)
Nikhil Mulley

1
@Nikhil: для цього вам не потрібно грати з dbus: gnome-screensaver-commandвже є. Перейшовши -aдо gnome-screensaver-commandвас, ви заблокуєте екран, при цьому розблокуйте його -d. У будь-якому випадку більшість програм gnome широко використовують dbus, тому ви зможете зробити багато дивовижних речей з ним.
перо

1
@peoro Дякую чудово, дуже корисно! Чи можу я також запустити це як якийсь демон? Коли я зараз ввожу це в терміналі, він повинен залишатися відкритим, щоб стежити за dbus для цього випадку. Я хотів би виконати цю команду при вході в систему і тоді вона може бути активною протягом усього сеансу.
Сандер

1
Я думаю, що все може змінитися зараз у 2014 році? як вихід не змінюється, якщо екран був лише заблокований, він показує лише щось, коли він заблокований і сильно відрізняється від цього :(, я створив це питання askubuntu.com/questions/505681/… , чи вірите ви, що все ще є спосіб зробити це? thx!
Сила Водолія

Як запустити цей скрипт, який охоплює подію блокування? Ніби як спостерігач.
Starx

20

У ubuntu 14.04 подія DBus для розблокування екрана змінилася, і новий сценарій прив’язки до подій блокування екрана та розблокування виглядає наступним чином

dbus-monitor --session "type='signal',interface='com.ubuntu.Upstart0_6'" | \
(
  while true; do
    read X
    if echo $X | grep "desktop-lock" &> /dev/null; then
      SCREEN_LOCKED;
    elif echo $X | grep "desktop-unlock" &> /dev/null; then
      SCREEN_UNLOCKED;
    fi
  done
)

ідеї, як зробити цю роботу на Fedora 23?
Рей Фосс


@JacobVlijm Дякую за тестування цього та зелене освітлення, яке я можу використовувати сьогодні ввечері :)
WinEunuuchs2Unix

6

Сьогодні я думаю, що краще слухати повідомлення, LockedHintа не заставки. Таким чином, ви не прив’язані до реалізації заставки.

Ось простий сценарій для цього:

gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint

Дає це:

/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <true>}, @as [])
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <false>}, @as [])

5

Ubuntu 16.04: рішення ozma не працювало для мене, однак це:

dbus-monitor --session "type=signal,interface=com.canonical.Unity.Session,member=Unlocked" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | awk '{print $NF}'`
    if [[ "$LOCK_STAT" == "member=Unlocked" ]]; then
        echo "was unlocked"
    fi
  done

Це може спрацювати над Unity, але питання стосувалося Гнома.
cprn

5

Розгортання вже даної відповіді.

Якщо ви спробуєте запустити сценарій всередині screenабо tmuxсеансу, вам потрібно спочатку знайти правильний $DBUS_SESSION_BUS_ADDRESSі передати його як аргумент dbus-monitorзамість --session. Крім того, якщо ви запускаєте його як демон, ви повинні переконатися, що одночасно працює лише один екземпляр (наприклад, з файлом блокування), і що сценарій очищається після себе trap. Наступний приклад буде працювати як демон у більшості поточних середовищ Gnome (тестований на Ubuntu GNOME 16.04):

#!/bin/bash
set -o nounset                # good practice, exit if unset variable used

pidfile=/tmp/lastauth.pid     # lock file path
logfile=/tmp/lastauth.log     # log file path

cleanup() {                   # when cleaning up:
    rm -f $pidfile            # * remove the lock file
    trap - INT TERM EXIT      # * reset kernel signal catching
    exit                      # * stop the daemon
}

log() {                       # simple logging format example
    echo $(date +%Y-%m-%d\ %X) -- $USER -- "$@" >> $logfile
}

if [ -e "$pidfile" ]; then    # if lock file exists, exit
    log $0 already running...
    exit
fi

trap cleanup INT TERM EXIT    # call cleanup() if e.g. killed

log daemon started...

echo $$ > $pidfile            # create lock file with own PID inside

# usually `dbus-daemon` address can be guessed (`-s` returns 1st PID found)
export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pidof -s dbus-daemon)/environ)

expr='type=signal,interface=org.gnome.ScreenSaver' # DBus watch expression here

dbus-monitor --address $DBUS_SESSION_BUS_ADDRESS "$expr" | \ 
    while read line; do
        case "$line" in
            *"boolean true"*) log session locked;;
            *"boolean false"*) log session unlocked;;
        esac
    done

cleanup # let's not leave orphaned lock file when the loop ends (e.g. dbus dies)

Якщо це не працює для вас, можливо, це:

  1. ви не використовуєте Gnome - перевірте інші відповіді для кращого вираження перегляду DBus.
  2. ви запускаєте кілька рядків DBus - перевірте деталі, як зробити пошук PID детермінованим.

1
Це насправді відповідає на інше запитання щодо динамічного виявлення інформації про сеанс DBus, що задається обліковим записом користувача, яке я тут вирішив . Дякуємо за ваш внесок тут!
Нафтулі Кей

Дякую. Я зв’яжу ваше рішення у відповіді для подальшого читання.
cprn

4

Якщо ви перебуваєте на Kubuntu або використовуєте KDE / Plasma в якості робочого середовища, вам потрібно прослухати інтерфейс org.freedesktop.ScreenSaver, тому сценарій для прослуховування цієї події виглядатиме так:

dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

1
Якщо ви використовуєте KDE / Plasma ви можете використовувати налаштування Plasma Desktop для виконання скриптів на повідомленнях ... Personalization>Notifications>Notifications>Screensaver.
ксеноїд

дякую @xenoid! KDE - це таке персональне завдання, що вам ніколи не доведеться вовтузитися з цими речами. це ніби вони передбачають, що мені потрібно
Ankur S

0

upstart Підтримка завдань сесіїdesktop-lock та desktop-unlockподії в start onстрофі. Просто створіть роботу .conf для свого користувача з відповідними тригерами та командами для виклику під $XDG_CONFIG_HOME/upstart/чи $HOME/.config/upstartподібним прикладом нижче:

description "some job description"
start on desktop-lock
script
        /path/to/your/executable
end script

-1

це те, що працювало для мене в ubuntu 16.04

dbus-monitor --session "type=signal,interface=org.gnome.ScreenSaver" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | grep boolean | awk '{print $2}'`
    if [[ "$LOCK_STAT" == "true" ]]; then
        echo "was locked"
    else
        echo "was un-locked"
    fi
  done

Це не спрацювало для мене. Як вона закінчила виконання і не слухає змінився стан.
Starx

яку заставку ви використовуєте? gnome чи xscreensaver? який аромат ubuntu, xubuntu, kubuntu тощо. яка версія (протестована 16.04)
озма

ubuntu gnome 16.04
Starx
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.