systemd サービスファイルの DISPLAY 設定

systemd サービスファイルの DISPLAY 設定

xclockをサービスとして起動し、システムサービスを学習しようとしています。サービスファイルは次のとおりです。

[Unit]
Description=clock

[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/xclock

[Install]
WantedBy=graphical.target

ここで何が起こっているのかというアイデアはありますか? 「モニターに接続できません」というエラーメッセージが表示されます。

答え1

アプリケーションがXモニターでウィンドウを開くには2つのことが必要です。 Xモニターの位置を知る必要があり、これはDISPLAY環境変数を介して渡されます。また、X サーバーに対する認証が必要です。これは、Xサーバーの起動時に生成される秘密の値であるCookieを介して渡され、Xサーバーを起動したユーザーのみがアクセスできるファイルに保存されます。デフォルトのCookieファイルは~/.Xauthority

XサーバーがデフォルトのCookieファイルの場所を使用している場合(Xでログインしたユーザーのホームディレクトリであると仮定)、追加はEnvironment=XAUTHORITY=/home/dogs/.Xauthority機能します。/home/dogs場所を見つけるには、次を参照してください。他のユーザーのデスクトップからrootとしてグラフィカルプログラムを起動できますか?そしてリモートXモニターでウィンドウを開く(「モニターを開けません」理由)?

または、Cookieファイルがデフォルトの場所にある場合は、Xサーバーを実行しているユーザーとしてプログラムを実行すると機能します(そうでない場合は、ルートケースのようにCookieファイルを見つける必要があります)。ディレクティブを追加しますUser(例User=dogs:)。

もちろん、指定したユーザーが所有する番号にXが表示されない場合、サービスは実行されません。

SystemdでGUIプログラムを起動するのはかなり奇妙です。このために設計されていません。 GUIプログラムは、ユーザーが開始したXセッション内に存在します。 Systemdはシステムプロセス用です。デーモンを使ってみてください。

答え2

現代的なアプローチ(2021)は、ユニットファイルに環境をハードコーディングしません.service。代わりに、次のようにしてください。

$ cat /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
#!/bin/sh

systemctl --user import-environment DISPLAY XAUTHORITY

if command -v dbus-update-activation-environment >/dev/null 2>&1; then
    dbus-update-activation-environment DISPLAY XAUTHORITY
fi

たとえば、Arch Linuxがこれを行います。

注:X11を起動するとDISPLAY環境XAUTHORITY変数が継承されます。みんなsystemdユーザーサービスユニットファイル(つまり、systemdによって管理されるファイルsystemd --user

を実行して、これらの設定が正しいことを確認できますsystemctl --user show-environment

Environment=これにより、ファイルでディレクティブを使用する必要がなくなります.service

答え3

以下を追加できます.xinitrc

xhost si:localuser:$USER

これは私にとって効果的です!

関連情報