Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

Wayland環境での.profile代替手段 デスクトップ・ログイン時の環境変数と自動実行

Linuxでのデスクトップ環境としてWayland*1が一般的になりつつある。そしてClear LinuxもWaylandへ向かっている*2

X11環境からWaylandへの移行において、ユーザーが真っ先に直面するのがログイン時の環境設定だろう。従来、ログイン時に読み込まれていた.profileが、Wayland環境では参照されないからだ。

おそらく、ほとんどのユーザーは.profileを利用して、次の2つに対応していたのではないだろうか。

Waylandにおいても、従来通りに.profileを参照することは可能だし、"source .profile"を実行しても良い。ただ同じことを起動時に対応しようと思えば、異なる対応が求められる。この投稿では、それぞれの対応を含む3つのアプローチを紹介する。

Wayland

環境変数

まず、それぞれの対応事項について分けて考える必要がある。まずは環境変数だ。Waylandでは、環境変数は次のファイルで設定する。

~/.config/environment.d/envvars.conf

wiki.archlinux.jp

自動起動

次の2つの方法がある。

デスクトップエントリの作成 デスクトップ・ログイン時に有効
「systemctl --user」の活用 デスクトップでなくとも有効
デスクトップエントリ

デスクトップエントリとは「.desktop」というファイルを指している。これを所定のフォルダに格納することで、デスクトップ環境の諸設定を運用管理できる。自動起動の場合は、次のファイルを編集する。

~/.config/autostart/.desktop

この方法は、言うなればWindowsで言うところのスタートアップ設定に相当する。ユーザーがデスクトップ環境にログインしたときに機能する。デスクトップ環境でなければ機能しない。

wiki.archlinux.jp
wiki.archlinux.jp

systemd (systemctl --user)

サービスを管理するsystemdのユーザーインスタンスを利用して、コマンドを実行させる方法がある。この方法は、言うなればWindowsで言うところのTask Schedulerを用いる方法に相当する。デスクトップエントリと異なり、必ずしもユーザーがデスクトップ環境にログインする必要もない。

特に自動起動の場合は、次のパスにユーザーユニット(serviceファイル)を作成する。

~/.config/systemd/user/

wiki.archlinux.jp

アプローチ

ここまでの方法を活用して、"source .profile"の代替手段を実装してみる。3つのアプローチが考えられる。

アプローチ1 デスクトップエントリから「source .profile」を実行する
アプローチ2 環境変数をenvvars.confに設定する
.profile中のコマンドをデスクトップエントリに設定する
アプローチ3 環境変数をenvvars.confに設定する
.profile中のコマンドをユーザーユニットに設定する

.profileには次の設定が含まれているとしよう。以上のアプローチで、この設定を置き換えていく。

.profileの設定

export DOTNET_ROOT=~/.dotnet
export PATH=$PATH:$DOTNET_ROOT
export PATH=$PATH:$DOTNET_ROOT/tools

export PATH=$PATH:~/.local/bin

distrobox enter -n ubuntu -- ibus-daemon -drx

ちなみに、これはPwerShell用の環境変数を定義し*3、Distroboxを介して動作するUbuntuコンテナ上のMozcを有効化*4している。

アプローチ1

デスクトップエントリーの自動起動を利用する。この方法は、ユーザーがデスクトップ環境へログインする際に機能する。最も簡単だが、邪道な方法でもある。Wayland環境とX11環境を切り替えて使用する場合、X11では.profileが重複実行されるからだ。

次のように「~/.config/autostart/.desktop」を作成する。注意したいのは、「Exec=」に指定するパスを絶対パスとすることだ。次回ログイン時から、.profile中の記述が有効となる。

~/.config/autostart/.desktop

[Desktop Entry]
Comment=read .profile
Exec=/bin/bash -lc 'source /home/[user name]/.profile'
Name=autoexec
Type=Application

アプローチ2

環境変数をconfファイルに定義し、自動起動をデスクトップエントリに指定する。デスクトップにログインする際の自動起動を設定するための、もっとも正当な方法だ。

まず環境変数を「~/.config/environment.d/envvars.conf」に定義する。

~/.config/environment.d/envvars.conf

DOTNET_ROOT=~/.dotnet
PATH=$PATH:$DOTNET_ROOT
PATH=$PATH:$DOTNET_ROOT/tools

PATH=$PATH:~/.local/bin

次に「~/.config/autostart/.desktop」を作成する。やはり、「Exec=」に指定するパスを絶対パスとすること。次回ログイン時から、全ての設定が反映される。

~/.config/autostart/.desktop

[Desktop Entry]
Comment=run Mozc at login
Exec=/home/[user name]/.local/bin/distrobox enter -n ubuntu -- ibus-daemon -drx
Name=autoexec
Type=Application

アプローチ3

アプローチ2と同様に正当な方法ではあるのだが、特にデスクトップ環境にログインする際の自動起動に限定すれば、若干邪道な方法でもある。ユーザーがログインしなくても実行させることもできるし、厄介なのは手動で「source .profile」を実行するのとは異なり、カレントシェルへの継承など、期待通りの状況にならないことがあることだ。

envvars.confへ環境変数を定義するのは、アプローチ2と同じだ。ユーザーユニットを、次のように作成した。ちなみにserviceファイルの名前は任意で構わない。そして、やはり「ExecStart=」のパスは絶対パスで記述すること。

~/.config/systemd/user/autoexec.service

[Unit]
Description=run Mozc at login

[Service]
ExecStart=/home/[user name]/.local/bin/distrobox enter -n ubuntu -- ibus-daemon -drx

[Install]
WantedBy=default.target

このユーザーユニットを、次のコマンドで登録する。コマンド実行後、再ログイン、あるいは再起動すると、ユーザーのログイン時にユーザーユニットが実行される。

systemctl --user enable autoexec.service
systemctl --user daemon-reload

もしユーザーユニットを編集した場合、次のコマンドで再登録する。

systemctl --user disable autoexec.service
systemctl --user enable autoexec.service
systemctl --user daemon-reload