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
これは私にとって効果的です!