Executar script no bloqueio / desbloqueio da tela


54

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

Respostas:


49

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 isso faz o que você precisa a qualquer momento, dbus-monitorimprime uma linha sobre a tela ser bloqueada / desbloqueada.


Aqui está 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_LOCKEDe echo SCREEN_UNLOCKEDcom o que você precisa.


Oi @peoro, Isso me faz pensar que você pode desbloquear ou bloquear gnome ecrã / sessão de um programa roteirizado, vale a pena fazer alguns truques ssh sobre isso ;-)
Nikhil Mulley

11
@ Nikhil: para fazer isso, você não precisa brincar com o dbus: gnome-screensaver-commandjá está lá. Passando -apara gnome-screensaver-commandvocê bloqueia a tela, enquanto a desbloqueia -d. De qualquer forma, a maioria dos aplicativos gnome usa o dbus extensivamente, para que você possa fazer muitas coisas incríveis com ele.
peoro

11
@peoro Muito obrigado, muito útil! Também posso executar isso como uma espécie de daemon? Quando eu insiro isso no terminal agora, ele deve permanecer aberto para monitorar o dbus para esse caso. Eu gostaria de executar este comando no login e, em seguida, ele pode estar ativo durante toda a sessão.
Sander

11
Eu acho que as coisas podem ter mudado agora em 2014? como a saída não muda se a tela estiver bloqueada apenas, ela mostra algo quando fica em branco e é muito diferente daqui :(, eu criei esta pergunta askubuntu.com/questions/505681/… , você acredita que ainda há alguma maneira de fazer isso? thx!
Aquarius Power

Como executar esse script que captura o evento de bloqueio? Como um observador.
Starx

20

No ubuntu 14.04, o evento DBus para desbloqueio de bloqueio de tela foi alterado e o novo script para ligação aos eventos de bloqueio e desbloqueio de tela 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
)

idéias sobre como fazer isso funcionar no fedora 23?
Raio Foss

2
Também funciona bem em 16.04
Jacob Vlijm 29/11

@JacobVlijm Obrigado por testar isso e iluminá-lo para que eu possa usá-lo hoje à noite :)
WinEunuuchs2Unix 8/16/16

6

Hoje em dia, acho melhor ouvir as LockedHintmensagens do que proteger as telas. Dessa forma, você não está vinculado a uma implementação de proteção 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 [])

5

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

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

Pode funcionar no Unity, mas a pergunta era em relação ao Gnome.
CPRN

5

Expandindo a resposta já dada.

Se você tentar executar um script a partir de uma sessão screenou tmux, precisará encontrar o correto $DBUS_SESSION_BUS_ADDRESSprimeiro e passá-lo como argumento para, em dbus-monitorvez de --session. Além disso, se você o estiver executando como um daemon, verifique se apenas uma instância está sendo executada por vez (por exemplo, com um arquivo de bloqueio) e se o script é limpo por si próprio 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 para você, provavelmente é porque:

  1. você não usa o Gnome - verifique outras respostas para obter uma melhor expressão do relógio DBus.
  2. você executa várias linhas DBus - verifique detalhes sobre como tornar a descoberta de PID determinística.

11
Na verdade, isso responde a uma pergunta diferente que eu tinha para descobrir dinamicamente as informações da sessão DBus, dada uma conta de usuário, que eu resolvi aqui . Obrigado pela sua contribuição aqui!
Naftuli Kay 02/06

Obrigado. Vincularemos sua solução na resposta para outras leituras.
CPRN

4

Se você estiver no Kubuntu ou estiver usando o KDE / Plasma como seu ambiente de área de trabalho, terá que ouvir a interface org.freedesktop.ScreenSaver, para que o script para ouvir esse evento fique 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

11
Se você usa KDE / Plasma você pode usar as configurações de Plasma Desktop para executar scripts em notificações ... Personalization>Notifications>Notifications>Screensaver.
xenoid 03/04

obrigado @xenoid! O KDE é tão personalizável que você nunca precisa mexer nessas coisas. é como se eles antecipassem o que eu preciso
Ankur S

0

upstart suporte a tarefasdesktop-lock e desktop-unlockeventos da sessão em start onestrofe. Basta criar um trabalho .conf para seu usuário com acionadores e comandos relevantes para chamar no exemplo $XDG_CONFIG_HOME/upstart/ou $HOME/.config/upstartabaixo, como abaixo:

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

-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

Isso não funcionou para mim. Como terminou a execução e não escuta o estado mudou.
Starx

qual protetor de tela você está usando? gnome ou xscreensaver? que ubuntu sabor, xubuntu, kubuntu etc, que versão (que foi testado em 16,04)
ozma

ubuntu gnome 16.04
Starx
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.