Uruchom skrypt na ekranie blokady / odblokowania


54

Chciałbym uruchomić ekran, jeśli sesja Gnome jest zablokowana i odblokowana. Czy istnieje sposób, w jaki mogę to przechwycić i wykonać pewne czynności, gdy pulpit jest zablokowany lub odblokowany?

Odpowiedzi:


49

Wygaszacz ekranu Gnome emituje pewne sygnały na dbus, gdy coś się dzieje.

Tutaj dokumentacja (z kilkoma przykładami).

Możesz napisać skrypt, który działa:

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

i to robi to, czego potrzebujesz w dowolnym momencie, dbus-monitordrukuje wiersz o zablokowanym / odblokowanym ekranie.


Oto polecenie bash, aby zrobić to, czego potrzebujesz:

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

Wystarczy wymienić echo SCREEN_LOCKEDi na echo SCREEN_UNLOCKEDto, czego potrzebujesz.


Cześć @peoro, to sprawia, że ​​myślę, że możesz odblokować lub zablokować ekran gnome / sesję ze skryptu, warto zrobić kilka sztuczek ssh o tym ;-)
Nikhil Mulley

1
@Nikhil: aby to zrobić, nie musisz się bawić z dbus: gnome-screensaver-commandjuż tam jest. Przechodząc -ado gnome-screensaver-commandciebie będzie zablokować ekran, podczas gdy będziesz go odblokować -d. W każdym razie większość aplikacji gnome intensywnie korzysta z dbus, więc będziesz mógł robić z nim wiele niesamowitych rzeczy.
peoro

1
@peoro Dzięki wielkie, bardzo pomocne! Czy mogę również uruchomić to jako jakiś demon? Kiedy wprowadzę to teraz do terminala, musi on pozostać otwarty, aby monitorować dbus w tym przypadku. Chciałbym wykonać to polecenie podczas logowania, a następnie może być aktywne podczas całej sesji.
Sander,

1
Myślę, że wszystko mogło się teraz zmienić w 2014 roku? ponieważ wyjście nie zmienia się, jeśli ekran był tylko zablokowany, pokazuje tylko coś, gdy jest wygaszony i różni się bardzo od tego tutaj :(, stworzyłem to pytanie askubuntu.com/questions/505681/... , czy wierzysz, że wciąż jest trochę sposób na zrobienie tego? dzięki!
Aquarius Power

Jak uruchomić skrypt, który przechwytuje zdarzenie blokady? Trochę jak obserwator.
Starx,

19

W Ubuntu 14.04 zdarzenie DBus dla odblokowania blokady ekranu zmieniło się, a nowy skrypt do powiązania z zablokowaniem i odblokowaniem ekranu wygląda następująco

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
)

pomysły, jak sprawić, by działało to na Fedorze 23?
Ray Foss 30.04.16

2
Działa również dobrze 16.04
Jacob Vlijm

@JacobVlijm Dzięki za przetestowanie tego i zielone oświetlenie, żebym użył tego wieczora :)
WinEunuuchs2Unix

6

W dzisiejszych czasach myślę, że lepiej jest słuchać LockedHintwiadomości zamiast wygaszacza ekranu. W ten sposób nie jesteś przywiązany do implementacji wygaszacza ekranu.

Oto prosty skrypt, aby to zrobić:

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

Daje to:

/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: rozwiązanie ozma nie działało dla mnie, jednak to:

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

Może działać na Unity, ale pytanie dotyczyło Gnome'a.
cprn

5

Rozwijanie już udzielonej odpowiedzi.

Jeśli spróbujesz uruchomić skrypt z wnętrza sesji screenlub tmux, najpierw musisz znaleźć poprawny $DBUS_SESSION_BUS_ADDRESSi przekazać go jako argument dbus-monitorzamiast --session. Również jeśli uruchamiasz go jako demon, powinieneś upewnić się, że działa tylko jedna instancja na raz (np. Z plikiem blokady) i że skrypt czyści się po sobie trap. Poniższy przykład będzie działał jako demon w większości obecnych środowisk Gnome (testowany na 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)

Jeśli to nie działa, prawdopodobnie dlatego, że:

  1. nie korzystasz z Gnome - sprawdź inne odpowiedzi, aby uzyskać lepszą obserwację DBus.
  2. prowadzisz wiele linii DBus - sprawdź szczegóły, jak sprawić, by PID był deterministyczny.

1
To faktycznie odpowiada na inne pytanie, które miałem do dynamicznego odkrywania informacji o sesji DBus, biorąc pod uwagę konto użytkownika, które tutaj rozwiązałem . Dziękuję za Twój wkład tutaj!
Naftuli Kay

Dzięki. Połączę twoje rozwiązanie w odpowiedzi do dalszego czytania.
cprn

4

Jeśli korzystasz z Kubuntu lub używasz KDE / Plazmy jako środowiska graficznego org.freedesktop.ScreenSaver, musisz nasłuchiwać interfejsu , więc skrypt do odsłuchiwania tego zdarzenia wyglądałby następująco:

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
Jeśli używasz KDE / ściany można użyć ustawień Plasma Desktop do wykonywania skryptów na zawiadomień ... Personalization>Notifications>Notifications>Screensaver.
ksenoid

dzięki @xenoid! KDE jest tak spersonalizowanym de, że nigdy nie musisz majstrować przy tych rzeczach. to tak, jakby oczekiwali tego, czego potrzebuję
Ankur S

0

upstart wsparcie zadania sesjidesktop-lock i desktop-unlockwydarzenia w start onzwrotce. Wystarczy utworzyć zadanie .conf dla użytkownika z odpowiednimi wyzwalaczami i poleceniami do wywołania poniżej $XDG_CONFIG_HOME/upstart/lub $HOME/.config/upstartpodobnego przykładu poniżej:

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

-1

to działało dla mnie w 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

To mi nie zadziałało. Po zakończeniu wykonywania i nie oczekuje zmiany stanu.
Starx,

jakiego wygaszacza ekranu używasz? gnome czy xscreensaver? jaki smak ubuntu, xubuntu, kubuntu itp. która wersja (przetestowana 16.04)
ozma

ubuntu gnome 16.04
Starx
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.