Systemd sleep.target for user level

Diego Fernández Giraldo
2 min readJan 28, 2019

At one point, I got carried away making a bunch of user level services for Systemd. It’s a neat way to run scripts during user sessions providing cool functionality like handling dependencies and automatic restarts. One issue I ran into was that I couldn’t create units depending on system level targets. I wanted to have some user level units that depended on the sleep.target, but I was blocked for a while. At some point I was introduced to dbus-monitor, which I immediately realized this could be used to build out monitor services to watch for system level events. I was able to create my own sleep.target using the following scripts and services. I’m sure this could be simplified, but this works fine for my purposes :)

~/.local/share/systemd/user/sleep.target

[Unit]
Description=User level sleep target
StopWhenUnneeded=yes

~/.local/bin/watch_sleep

#!/bin/bashdbus-monitor --system "type='signal',interface='org.freedesktop.login1.Manager',member=PrepareForSleep" | while read x; do
case "$x" in
*"boolean false"*) systemctl --user --no-block stop sleep.target;;
*"boolean true"*) systemctl --user --no-block start sleep.target;;
esac
done

~/.local/share/systemd/user/watch_sleep.service

[Unit]
Description=watch for sleep signal to start sleep.target
After=started.target
[Service]
ExecStart=/bin/bash -c watch_sleep
Restart=on-failure
[Install]
WantedBy=started.target

I use a started.target which I start in my .zprofile after setting some env variables and adding them to systemd using dbus-update-activation-environment --systemd, but you could replace that with default.target. I also use /bin/bash -c to run the script since that will pick up my PATH, so you might need to change that with the full path.

Using a similar approach you could create some usable targets such asunlocked.target using

~/.local/bin/watch_unlock

#!/bin/bashdbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | while read x; do
case "$x" in
*"boolean false"*) systemctl --user --no-block start unlocked.target;;
*"boolean true"*) systemctl --user --no-block stop unlocked.target;;
esac
done

You might be able to get some inspiration from my dotfiles (https://github.com/aiguofer/dotfiles). If you got some other cool targets or units, please share in comments!

--

--

Diego Fernández Giraldo

I’m Diego Fernández Giraldo, a Freelance Data Science Engineer looking to help your business succeed by ensuring you are leveraging data to its full potential.