1. Overview

Sometimes, we may need to run a script when a user locks and unlocks a session. For example, we may want to keep track of the times when these locks and unlocks occur for administrative purposes.

In this tutorial, we’ll discuss how to run a script when a user locks or unlocks a session. We’ll explore two commands, gdbus monitor and dbus-monitor. We’ll see that both commands depend on the D-Bus message bus system.

2. Logger Script

We’ll run the following script, session_logger.sh, when we lock or unlock a session:

#!/bin/bash

log_file=/tmp/session.log

if [[ "$1" == "true" ]]
then
    echo "Screen locked at `date`" >> $log_file
elif [[ "$1" == "false" ]]
then
    echo "Screen unlocked at `date`" >> $log_file
fi

We pass the argument true to session_logger.sh when we lock a session. In this case, the script appends the time we lock the session to log_file using echo “Screen locked at `date`” >> $log_file, where log_file is /tmp/session.log. We use the date command to get the time.

Similarly, we pass the argument false to session_logger.sh when we unlock a session. In this case, we append the time we unlock the session to log_file using echo “Screen unlocked at `date`” >> $log_file.

3. Using gdbus

gdbus is a versatile tool for working with D-Bus objects. It has several commands like printing the interfaces of a remote object, monitoring objects, invoking a method on a remote object, or emitting signals.

We can use the monitor command of gdbus for monitoring screen locks and unlocks. We can monitor screen locks and unlocks using the org.freedesktop.login1 D-Bus interface of the systemd-logind system service.

The systemd-logind system service manages user logins. In addition to a C library interface, it provides the org.freedesktop.login1 D-Bus interface.

We can use the LockedHint property of this interface to monitor screen locks and unlocks. This property is a read-only property of the org.freedesktop.login1 interface. Its value becomes true in the case of session lock and false in the case of session unlock.

3.1. Inspection of gdbus monitor

Let’s see how to use gdbus monitor for monitoring session locks and unlocks:

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

The -y option of gdbus monitor specifies connecting to the system bus. Additionally, the -d option specifies the destination name to monitor. We monitor the org.freedesktop.login1 D-Bus interface. We can use the –system and –dest options instead of the -y and -d options, respectively.

Since there may be many events about the org.freedesktop.login1 D-Bus interface, we filter the output of gdbus monitor using grep LockedHint.

Now, let’s lock the session by running xdg-screensaver lock in another terminal and then unlock the session manually to inspect the output of gdbus monitor:

$ 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 [])

There are two new lines of output. The first line is printed when we lock the session. In this case, the value of LockedHint is set to true, which is specified by {‘LockedHint’: } in the output.

The second line, on the other hand, is printed when we unlock the session. In this case, the value of LockedHint is set to false, as is apparent from {‘LockedHint’: } in the output.

3.2. Running the Logger Script

Now, we’ll see how to run the script, session_logger.sh, when we lock or unlock the session. We’ll use the following script, call_script_using_gdbus.sh:

#!/bin/bash

while read line 
do
    case "$line" in
        *"{'LockedHint': <true>}"*) ./session_logger.sh true;;
        *"{'LockedHint': <false>}"*) ./session_logger.sh false;;
    esac
done < <(gdbus monitor -y -d org.freedesktop.login1)

We pass the output of gdbus monitor -y -d org.freedesktop.login1 to the input of the while loop using process substitution, i.e., $( gdbus monitor -y -d org.freedesktop.login1). The while loop reads the output of gdbus monitor using the statement read line.

We check the existence of the strings “{‘LockedHint’: }” and “{‘LockedHint’: }” using a case statement. The existence of “{‘LockedHint’: }” in the output means that the session is locked. We run ./session_logger.sh true in this case. Otherwise, the session is unlocked, and we run ./session_logger.sh false.

We don’t need to filter the output of gdbus monitor using the grep LockedHint statement since we perform the filtering within the case statement.

Now, let’s run call_script_using_gdbus.sh in a terminal:

$ ./call_script_using_gdbus.sh

The script starts running. Now, after locking the session using xdg-screensaver lock and then unlocking the session, let’s check the content of /tmp/session.log:

 $ cat /tmp/session.log
Screen locked at Mon Oct 29 05:40:58 AM EDT 2023
Screen unlocked at Mon Oct 29 05:41:02 AM EDT 2023

As is apparent from the content of /tmp/session.log, we were successful in calling the logger script, session_logger.sh, when we locked the session. session_logger.sh appended the first line to /tmp/session.log since we called it by passing the argument true. Similarly, session_logger.sh appended the second line to /tmp/session.log when we unlocked the session. It called session_logger.sh by passing the argument false in this case.

4. Using dbus-monitor

The dbus-monitor command is useful for monitoring the messages in the D-Bus message bus. We must provide a set of watch expressions to dbus-monitor to monitor the messages we’re interested in.

The GNOME Screensaver provides the org.gnome.ScreenSaver D-Bus interface. This interface has a D-Bus signal named ActiveChanged. The ActiveChanged signal is emitted when a session lock or unlock occurs. The value of the signal’s field is true in the case of a session lock, and it’s false in the case of a session unlock.

Therefore, we can monitor session locks and unlocks using dbus-monitor together with the org.gnome.ScreenSaver D-Bus interface.

4.1. Inspection of dbus-monitor

Let’s see how to use dbus-monitor to monitor session locks and unlocks:

$ dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | grep -A1 ActiveChanged

The –session option of dbus-monitor specifies monitoring the session bus. Although we explicitly specify it, we can omit it since dbus-monitor monitors the session bus by default.

The watch expression we supply to dbus-monitor is “type=’signal’,interface=’org.gnome.ScreenSaver'”. The watch expression specifies that we want to monitor the signals of the org.gnome.ScreenSaver D-Bus interface.

We filter the output of dbus-monitor using grep -A1 ActiveChanged. The -A1 option of grep prints the searched line together with the line after the searched line.

Now, let’s lock the session from another terminal using xdg-screensaver lock and then unlock the session manually to inspect the output of dbus-monitor:

$ dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | grep -A1 ActiveChanged
signal time=1698680865.312399 sender=:1.16 -> destination=(null destination) serial=564 path=/org/gnome/ScreenSaver; interface=org.gnome.ScreenSaver; member=ActiveChanged
   boolean true
--
signal time=1698680874.126038 sender=:1.16 -> destination=(null destination) serial=591 path=/org/gnome/ScreenSaver; interface=org.gnome.ScreenSaver; member=ActiveChanged
   boolean false

As is apparent from the output, the first two lines correspond to the session lock. The value of the ActiveChanged signal is true in this case.

The last two lines, on the other hand, correspond to the session unlock. The value of the ActiveChanged signal is false in this case.

4.2. Running the Logger Script

Now, we’ll see how to run the script, session_logger.sh, when we lock or unlock the session. We’ll use the following script call_script_using_dbus_monitor.sh:

#!/bin/bash

while read x 
do
    case "$x" in
        *"boolean true"*) ./session_logger.sh true;;
        *"boolean false"*) ./session_logger.sh false;;
    esac
done < <(dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'")

The script looks like call_script_using_gdbus.sh. In this case, we pass the output of dbus-monitor –session “type=’signal’,interface=’org.gnome.ScreenSaver'” to the input of the while loop using process substitution. Additionally, we check the existence of the strings “boolean true” and “boolean false” in the case statement.

Now, let’s try the script by running it in a terminal:

$ ./call_script_using_dbus_monitor.sh

The script starts running. Now, after locking the session using xdg-screensaver lock and then unlocking the session, let’s check the content of /tmp/session.log:

 $ cat /tmp/session.log
Screen locked at Mon Oct 29 05:51:27 AM EDT 2023
Screen unlocked at Mon Oct 29 05:51:54 AM EDT 2023

The output is as expected. Therefore, we’re successful in running session_logger.sh when we lock and unlock the session.

5. Conclusion

In this article, we discussed how to run a script when a user locks or unlocks a session.

Firstly, we learned that we could use the gdbus monitor command together with the org.freedesktop.login1 D-Bus interface of the systemd-logind system service.

Then, we saw that we could also use the dbus-monitor command together with the GNOME Screensaver’s org.gnome.ScreenSaver D-Bus interface to monitor session locks and unlocks.