在屏幕锁定/解锁时运行脚本


54

如果Gnome会话已锁定和解锁,我想运行一个屏幕。当桌面处于锁定状态或解锁状态时,有没有办法可以拦截并执行某些操作?

Answers:


49

当某些事情发生时,Gnome屏幕保护程序会在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您需要的东西即可。


嗨@peoro,我认为您可以从脚本程序中解锁或锁定gnome屏幕/会话,值得做一些ssh技巧;-)
Nikhil Mulley,2012年

1
@Nikhil:要做到这一点,您不需要使用dbus:gnome-screensaver-command已经存在。传递-a到时,gnome-screensaver-command您将锁定屏幕,而使用则将其解锁-d。无论如何,大多数gnome应用程序都广泛使用dbus,因此您可以使用它执行许多令人惊奇的事情。
peoro 2012年

1
@peoro非常感谢,非常有帮助!我也可以将其作为某种守护程序运行吗?当我现在在终端中输入此命令时,它必须保持打开状态以监视dbus。我想在登录时执行此命令,然后可以在整个会话期间将其激活。
桑德2012年

1
我认为2014年现在情况可能会有所改变?因为如果仅锁定屏幕,输出不会改变,它只会在变黑时显示一些东西,并且与这里非常不同:(,我创建了这个问题askubuntu.com/questions/505681/…,您是否相信仍然存在一些问题这样做吗?thx!
Aquarius

如何运行捕获锁定事件的脚本?有点像守望者。
Starx '16

19

在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
)

如何在fedora 23上进行这项工作的想法?
雷·福斯

2
在16.04上也能正常工作
Jacob Vlijm '16

@JacobVlijm感谢您对此进行测试并为我今晚使用的
绿灯

6

如今,我认为最好听的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 [])

5

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

它可能适用于Unity,但有关Gnome的问题。
cprn

5

扩展已经给出的答案。

如果您尝试从screentmux会话中运行脚本,则需要先找到正确的脚本$DBUS_SESSION_BUS_ADDRESS并将其作为dbus-monitor而不是的参数传递--session。另外,如果您将其作为守护程序运行,则应确保一次仅运行一个实例(例如带有锁定文件的实例),并使用清除脚本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查找确定性的详细信息

1
这实际上回答了我在给定用户帐户的情况下动态发现DBus会话信息所遇到的另一个问题,我在这里已解决了这个问题。感谢您在这里的贡献!
纳夫特利凯

谢谢。我会在答案中链接您的解决方案,以供进一步阅读。
cprn

4

如果您使用的是Kubuntu或将KDE / Plasma用作桌面环境,则必须监听interface 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

1
如果你使用KDE /等离子可以使用Plasma桌面设置,以通知执行脚本... Personalization>Notifications>Notifications>Screensaver
xenoid

谢谢@xenoid!KDE是一种个性化的de,因此您无需费心处理这些事情。好像他们预料到我需要什么一样
Ankur S

0

upstart 节的工作支持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

-1

这是在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

这对我不起作用。当它完成执行并且不监听状态改变时。
Starx '16

您正在使用哪个屏幕保护程序?gnome或xscreensaver?哪种版本的ubuntu,xubuntu,kubuntu等(已在16.04上测试)
ozma

Ubuntu gnome 16.04
Starx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.