Vorrei eseguire uno schermo se la sessione di Gnome è bloccata e sbloccata. Esiste un modo per intercettarlo ed eseguire determinate azioni quando il desktop è bloccato o sbloccato?
Vorrei eseguire uno schermo se la sessione di Gnome è bloccata e sbloccata. Esiste un modo per intercettarlo ed eseguire determinate azioni quando il desktop è bloccato o sbloccato?
Risposte:
Gnome-screensaver emette alcuni segnali su dbus quando succede qualcosa.
Ecco la documentazione (con alcuni esempi).
È possibile scrivere uno script che esegue:
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"
e ciò fa quello che ti serve in qualsiasi momento dbus-monitor
stampa una riga sullo schermo bloccato / sbloccato.
Ecco un comando bash per fare ciò di cui hai bisogno:
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
Basta sostituire echo SCREEN_LOCKED
e echo SCREEN_UNLOCKED
con quello che ti serve.
gnome-screensaver-command
è già lì. Passando -a
a gnome-screensaver-command
bloccherai lo schermo, mentre lo sbloccherai con -d
. Ad ogni modo, la maggior parte delle app di gnome usa ampiamente dbus, quindi sarai in grado di fare molte cose fantastiche con esso.
In Ubuntu 14.04 l'evento DBus per lo sblocco del blocco dello schermo è cambiato e il nuovo script per l'associazione al blocco dello schermo e agli eventi di sblocco è simile al seguente
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
)
Oggi penso sia meglio ascoltare i LockedHint
messaggi piuttosto che screensaver. In questo modo non sei legato all'implementazione di uno screensaver.
Ecco un semplice script per farlo:
gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint
Dà questo:
/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 [])
Ubuntu 16.04: la soluzione di ozma non ha funzionato per me, tuttavia questa ha fatto:
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
Espandendo su risposta già data.
Se si tenta di eseguire uno script dall'interno di una screen
o di una tmux
sessione, è necessario trovare $DBUS_SESSION_BUS_ADDRESS
prima il corretto e passarlo come argomento per dbus-monitor
anziché --session
. Inoltre, se lo stai eseguendo come demone, dovresti assicurarti che sia in esecuzione solo un'istanza alla volta (ad es. Con un file di blocco) e che lo script ripulisca dopo se stesso con trap
. Il seguente esempio funzionerà come demone nella maggior parte degli ambienti Gnome attuali (testato su 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)
Se questo non funziona per te, è probabilmente perché:
Se usi Kubuntu o usi KDE / Plasma come ambiente desktop, devi ascoltare l'interfaccia org.freedesktop.ScreenSaver
, quindi lo script per ascoltare quell'evento sarebbe simile al seguente:
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
Personalization>Notifications>Notifications>Screensaver
.
upstart
supporto del lavoro di sessionedesktop-lock
ed desktop-unlock
eventi nella start on
stanza. Crea un job .conf per il tuo utente con trigger e comandi pertinenti da chiamare sotto $XDG_CONFIG_HOME/upstart/
o $HOME/.config/upstart
come nell'esempio seguente:
description "some job description"
start on desktop-lock
script
/path/to/your/executable
end script
questa potrebbe non essere la soluzione più pulita ma funziona per me quando dbus-monitor ...
non:
gdbus monitor -y -d org.freedesktop.login1 |\
grep --line-buffered -i "LockedHint" |\
sed -uE 's/.*LockedHint.*<(.*)>.*/\1/g'
Dovrebbe restituire un flusso di linee con stringhe 'true' o 'false'
Utilizzo: Fedora versione 30 (trenta)
questo è ciò che ha funzionato per me in 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