systemdのユーザーユニットに環境変数を設定したい場合はEnvironパラメータまたはhomectlで設定する
systemdにはユーザーユニットがあってサービスプログラムを起動できるけれど、これ自体は ~/.bash_profile などのプロファイルを実行しない。なので環境変数をユニットから起動するプログラムに渡したい場合はユニットの Environment= を使うか、または homectl で設定しなければならない。
具体例でいうと、~/.bash_profile に GNUPGHOME を設定した状態で gpg-agent をソケット経由で起動した場合。プロセスツリーは以下のようになる。
$ pstreesystemd─┬─Xwayland───4*[{Xwayland}] ├─dirmngr ├─ghostty─┬─bash───pstree │ └─20*[{ghostty}] ├─ghostty─┬─bash │ └─20*[{ghostty}] └─systemd─┬─(sd-pam) ├─gpg-agent─┬─scdaemon───2*[{scdaemon}] │ └─{gpg-agent} └─xdg-permission-───3*[{xdg-permission-}]ここで最上位にある systemd は init と呼ばれるPIDが1の systemd プロセスを意味する。
ターミナルプロセスの場合
Section titled “ターミナルプロセスの場合”まず GNUPGHOME が設定されている bash プロセスだけど、これは ghostty から起動される。ghostty の親が init なところは驚いたけど、それを無視すると一般的なツリー状態だと思う。
$ ps lax | grep -E 'PID|ghostt'F UID PID PPID PRI NI TIME COMMAND0 60331 176549 1 20 0 0:23 /usr/bin/ghostty0 60331 184679 1 20 0 0:10 /usr/bin/ghosttyそうして ghostty プロセスが GNUPGHOME 環境変数を持っている。親プロセスは init なので、ユーザーが ~/.bash_profile で設定した環境変数を知らない。なので ghostty がシェルを起動して各種プロファイルを読み込んでいるのだろう。それは environ ファイルからも読み取れる。
$ xargs -0 -a /proc/176549/environ -n1 echo | grep GNUPGGNUPGHOME=~/.local/share/gnupgsystemdユーザーユニットの場合
Section titled “systemdユーザーユニットの場合”gpg-agent はsystemdのユーザーユニットで起動する。このとき、親プロセスは systemd —user となっている。別途確認したけどプロセス 1395 の親プロセスは init だった。
$ ps lax | grep -E 'PID|gpg'F UID PID PPID PRI NI TIME COMMAND0 60331 188107 1395 20 0 0:00 /usr/bin/gpg-agent --supervised
$ ps aux | grep -E 'PID|1395'USER PID TIME COMMANDlufia 1395 0:00 /usr/lib/systemd/systemd --userこのプロセスはどちらも環境変数 GNUPGHOME を持っていない。しかし homectl で設定した環境変数は持っている。
$ systemctl --user show-environment | grep QT_IMQT_IM_MODULE=fcitx
$ xargs -0 -a /proc/1646/environ -n1 echo | grep QT_IMQT_IM_MODULE=fcitxなので、事前に環境変数をユニットへ渡したければ homectl で与えるか、明示的に Environment= パラメータで設定する必要がある。または、動的に設定したい値があるなら systemctl set-environment や systemctl import-environment を使う。