Executar script no bloqueio / desbloqueio da tela

48

Gostaria de executar uma tela se a sessão do Gnome estiver bloqueada e desbloqueada. Existe uma maneira que eu possa interceptar isso e executar determinadas ações quando a área de trabalho está bloqueada ou desbloqueada?

    
por Naftuli Kay 03.01.2012 / 03:14

9 respostas

40

O Gnome-screensaver emite alguns sinais no dbus quando algo acontece.

Aqui a documentação (com alguns exemplos) .

Você pode escrever um script que seja executado:

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

e que faz o que você precisa a qualquer momento dbus-monitor imprime uma linha sobre a tela sendo bloqueada / desbloqueada.

Aqui um comando bash para fazer o que você precisa:

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 substituir echo SCREEN_LOCKED e echo SCREEN_UNLOCKED pelo que você precisa.

    
por 03.01.2012 / 03:57
18

No ubuntu 14.04, o evento DBus para desbloquear o bloqueio de tela foi alterado e o novo script para vincular a bloqueio de tela e desbloquear eventos se parece com o seguinte

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
)
    
por 24.06.2015 / 16:38
4

Ubuntu 16.04: a solução da ozma não funcionou para mim, mas esta foi:

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
    
por 09.10.2016 / 14:09
3

Se você está no Kubuntu ou usando o KDE / Plasma como seu ambiente de desktop, você tem que ouvir a interface org.freedesktop.ScreenSaver , então o script para ouvir aquele evento seria assim:

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
    
por 27.04.2017 / 09:55
3

Expandindo a resposta já fornecida.

Se você tentar executar um script de dentro de uma sessão screen ou tmux , será necessário encontrar o $DBUS_SESSION_BUS_ADDRESS correto primeiro e passá-lo como um argumento para dbus-monitor em vez de --session . Além disso, se você estiver executando-o como um daemon, certifique-se de que apenas uma instância esteja sendo executada por vez (por exemplo, com um arquivo de bloqueio) e que o script seja limpo após trap . O exemplo a seguir funcionará como um daemon na maioria dos ambientes atuais do Gnome (testado no 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 isso não funcionar, provavelmente é porque:

  1. você não usa o Gnome - verifique outras respostas para obter uma melhor expressão de exibição do DBus
  2. você executa várias linhas DBus - verifique os detalhes sobre como tornar determinista o PID
por 01.06.2017 / 20:25
2

Hoje em dia, penso que é melhor ouvir as mensagens LockedHint do que as do protetor de tela. Dessa forma, você não está preso a uma implementação de protetor de tela.

Aqui está um script simples para fazer isso:

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

Dá isto:

/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 [])
    
por 11.06.2018 / 01:33
0

Onde escrever esse código e como ele será executado:

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
    
por 17.08.2018 / 09:21
0

upstart trabalho da sessão s support desktop-lock e desktop-unlock eventos em start on stanza . Basta criar um trabalho .conf para seu usuário com gatilhos e comandos relevantes para chamar em $XDG_CONFIG_HOME/upstart/ ou $HOME/.config/upstart , como no exemplo abaixo:

description "some job description"
start on desktop-lock
script
        /path/to/your/executable
end script
    
por 14.11.2018 / 20:53
-1

isto é o que funcionou para mim no 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
    
por 26.07.2016 / 19:02

Tags