web-dev-qa-db-ja.com

画面ロック/ロック解除でスクリプトを実行する

Gnomeセッションがロックおよびロック解除されている場合、画面を実行したいと思います。これをインターセプトして、デスクトップがロックまたはロック解除されているときに特定のアクションを実行する方法はありますか?

59
Naftuli Kay

Gnome-screensaverは、何かが起こったときに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必要なもので。

55
peoro

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
)
21
Luv Agarwal

最近では、スクリーンセーバーのメッセージよりも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 [])
6
Matthew

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
5

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
5
Bob

すでに与えられた答えを拡張します。

screenまたはtmuxセッション内からスクリプトを実行しようとする場合、まず正しい$DBUS_SESSION_BUS_ADDRESSを見つけて、dbus-monitorではなく--sessionの引数として渡す必要があります。また、デーモンとして実行している場合は、一度に1つのインスタンスのみが実行されていること(ロックファイルなどを使用)、および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の検索結果を確定的にする方法について 詳細 を確認してください。
5
cprn

このコードの記述場所と実行方法:

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
0
Shrawan Lal

KDEプラズマの場合、org.freedesktop.ScreenSaverと:

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

ただし、ロック/ロック解除アクションは2回報告されることに注意してください。次のスクリプトは、アクションを5秒以内に制限します(必要なコマンドが2回実行されるのを防ぐため)。

#!/bin/bash

screen_locked () {
    if [[ $firstrun == '' ]] || [[ $(expr $(date +%s) - $firstrun) -ge 5 ]]
    then
        screen_locked_core;
        firstrun=$(date +%s);
    fi
}

screen_locked_core () {
    echo locked
}

dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" |
while read x; do
    case "$x" in 
        *"boolean true"*) screen_locked;;
#       *"boolean false"*) screen_unlocked;;  
    esac
done
0
intika

Cinnamon Desktopのバージョン(Ubuntu 18.04):

dbus-monitor --session "type='signal',interface='org.cinnamon.ScreenSaver'" | \
(
  while true; do
    read X
    if echo $X | grep "boolean true" &> /dev/null; then
      echo `date` - SCREEN_LOCKED;
    Elif echo $X | grep "boolean false" &> /dev/null; then
      echo `date` - SCREEN_UNLOCKED;
    fi
  done
)
0
BloodBlight

HaterTotが別のバージョンをコメントしてくれてありがとう。 ubuntu 18.04でテスト済み

echo "start at `date`" >> ~/Documents/time-trecking.log
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 "locked `date +%s` `date`" >> ~/Documents/time-trecking.log
    Elif [[ "$LOCK_STAT" == "false" ]]; then
        echo "unlock `date +%s` `date`" >> ~/Documents/time-trecking.log
    fi
  done

[編集前]これは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
0
ozma

これは最もクリーンな解決策ではないかもしれませんが、dbus-monitor ... ではない:

gdbus monitor -y -d org.freedesktop.login1 |\
 grep --line-buffered -i "LockedHint" |\
 sed -uE 's/.*LockedHint.*<(.*)>.*/\1/g'

文字列「true」または「false」を含む行のストリームを返す必要があります

使用:Fedoraリリース30(30)

0
user2777461

upstartセッションジョブ s desktop-lockスタンザのdesktop-unlockおよびstart onイベントをサポートします。以下の例のように、$XDG_CONFIG_HOME/upstart/または$HOME/.config/upstartの下で呼び出す関連トリガーとコマンドを使用して、ユーザーのジョブ.confを作成するだけです。

description "some job description"
start on desktop-lock
script
        /path/to/your/executable
end script
0
Oleg V. Volkov