web-dev-qa-db-ja.com

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

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

systemctl --user start screenlock.serviceを実行すると、画面がすぐにロックされ、journalctl --user-unit screenlock.serviceにログメッセージが表示されるので、ExecStartは明らかに正しいです。

関連.xinitrcセクション

xautolock -locker slock &

同じファイルでシステムサービスを作成するworks(つまり、slockは再開時にアクティブ):

# ln -s "${HOME}/.config/systemd/user/screenlock.service" /usr/lib/systemd/system/screenlock.service
# systemctl enable screenlock.service
$ systemctl suspend

しかし、いくつかの理由により、$HOMEの外にユーザー固有のファイルを追加したくありません。

  • ユーザーサービスはシステムサービスから明確に分離する必要があります
  • スーパーユーザー特権を使用せずにユーザーサービスを制御する必要がある
  • 構成はバージョン管理が容易であるべき
18
l0b0

sleep.targetはシステムサービスに固有です。その理由は、 sleep.targetは、スリープ状態になるときに自動的にアクティブになる魔法のターゲットではありません。これは、システムをスリープ状態にするputが通常のターゲットであるだけなので、当然、「ユーザー」インスタンスには同等のものはありません。 (残念ながら、現在「ユーザー」インスタンスはシステム全体のサービスに依存する方法がありません。)

(つまり、「ハードコーディング$ DISPLAY」ビジネス全体があります。非常にマルチユーザー/マルチシートのUNIXベースのOSでセッションパラメータをハードコーディングするたびに、rootは子猫を殺します。)

したがって、これを行うには2つの良い方法があります(2つ目の方法をお勧めします)。

方法1

システムがスリープ状態になったときにsystemd-logindが「すべてのセッションをロック」信号をブロードキャストするようにするシステムサービス(またはsystemd-sleep(8)フック)を作成します。

ExecStart=/usr/bin/loginctl lock-sessions

次に、X11セッション内(つまり、〜/ .xinitrcから)で、信号に反応する何かを実行します。

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

(GNOME、シナモン、KDE、 啓発 これはすでにネイティブでサポートされています。)

方法2

X11セッション内で、システムがスリープ状態になるのを直接監視する何かを実行します。 systemd-logindの「阻害剤」にフックする。

前述のxss-lockは、明示的な「すべてロック」信号がなくても、実際にそれを正確に実行するため、実行するだけで十分です。

xss-lock  slock&

Systemd-logindがコンピューターを一時停止する準備をしているのを見るとすぐにslockを実行します。

20
user1686