如何运行 systemd 用户服务以触发睡眠(又名挂起、休眠)?

l0b*_*0b0 19 arch-linux sleep suspend hibernate systemd

根据我拼凑的各种来源~/.config/systemd/user/screenlock.service

[Unit]
Description=Lock X session
Before=sleep.target

[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/xautolock -locknow

[Install]
WantedBy=sleep.target
Run Code Online (Sandbox Code Playgroud)

我已经使用systemctl --user enable screenlock.service. 但是在重新启动、登录、暂停和恢复(systemctl suspend通过关闭盖子进行测试)后,屏幕没有锁定,并且journalctl --user-unit screenlock.service. 我究竟做错了什么?

运行DISPLAY=:0 /usr/bin/xautolock -locknow会按预期锁定屏幕。

$ systemctl --version
systemd 215
+PAM -AUDIT -SELINUX -IMA -SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ +SECCOMP -APPARMOR
$ awesome --version
awesome v3.5.5 (Kansas City Shuffle)
 • Build: Apr 11 2014 09:36:33 for x86_64 by gcc version 4.8.2 (nobody@)
 • Compiled against Lua 5.2.3 (running with Lua 5.2)
 • D-Bus support: ?
$ slim -v
slim version 1.3.6
Run Code Online (Sandbox Code Playgroud)

如果我systemctl --user start screenlock.service立即运行屏幕锁定并在 中收到一条日志消息journalctl --user-unit screenlock.service,那么ExecStart显然是正确的。

相关.xinitrc部分

xautolock -locker slock &
Run Code Online (Sandbox Code Playgroud)

使用相同的文件创建系统服务有效(即slock在恢复时处于活动状态):

# ln -s "${HOME}/.config/systemd/user/screenlock.service" /usr/lib/systemd/system/screenlock.service
# systemctl enable screenlock.service
$ systemctl suspend
Run Code Online (Sandbox Code Playgroud)

$HOME出于以下几个原因,我不想在外部添加特定于用户的文件:

  • 用户服务应与系统服务明确分离
  • 应该在不使用超级用户权限的情况下控制用户服务
  • 配置应该易于版本控制

use*_*686 21

sleep.target特定于系统服务。原因是,sleep.target不是在睡觉时自动激活的魔法目标。它只是一个系统进入睡眠状态的常规目标——所以“用户”实例当然不会有等价物。(不幸的是,“用户”实例目前无法依赖系统范围的服务。)

(那个,还有整个“硬编码 $DISPLAY”业务。每次在基于大量多用户/多席位 Unix 的操作系统中硬编码会话参数时,root 都会杀死一只小猫。)

所以有两种好方法可以做到这一点(我建议第二种):

方法一

创建一个系统服务(或 systemd-sleep(8) 钩子),使 systemd-logind 在系统进入睡眠状态时广播“锁定所有会话”信号:

ExecStart=/usr/bin/loginctl lock-sessions
Run Code Online (Sandbox Code Playgroud)

然后,在您的 X11 会话中(即来自 ~/.xinitrc),运行一些对信号做出反应的东西:

systemd-lock-handler slock &
xss-lock --ignore-sleep slock &

(GNOME、Cinnamon、KDE、Enlightenment已经原生支持这一点。)

方法二

在您的 X11 会话中,运行一些直接监视系统进入睡眠状态的程序,例如通过连接到 systemd-logind 的“抑制剂”。

前面提到的 xss-lock 实际上就是这样做的,即使没有显式的“lock all”信号,所以让它运行就足够了:

xss-lock 锁&

它会在slock看到 systemd-logind 准备挂起计算机时立即运行。