TL;DR
この記事ではappendWindowsPath
を通常通り使用することを断念し、以下のようにPowerShellを直呼びして対応しました。
# WindowsのPATHを取得して統合する関数
function append_windows_path() {
# WindowsのシステムPATHを取得
local sys_path=$(/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command '[System.Environment]::GetEnvironmentVariable("Path", "Machine")' | tr -d '\r\n')
# WindowsのユーザーPATHを取得
local user_path=$(/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command '[System.Environment]::GetEnvironmentVariable("Path", "User")' | tr -d '\r\n')
# それぞれのPATHを統合
local win_path="$sys_path;$user_path"
# WindowsのPATH記法をBashの形式に変換
local wsl_path=$(printf '%s' "$win_path" | sed 's/;/\n/g' | sed -e 's#\([A-Za-z]\):\\#\/mnt\/\L\1\/#g' -e 's#\\#\/#g' | tr '\n' ':' | sed 's/:$//')
# WSLのPATHに追加。この際/usr/lib/wsl/libも追加する
export PATH="$PATH:/usr/lib/wsl/lib:$wsl_path"
}
# wsl.confをチェックして関数を呼び出す
append_path_enabled="true"
if [ -f /etc/wsl.conf ]; then
# appendWindowsPathの設定を取得
append_path_enabled=$(grep -i '^\s*appendWindowsPath\s*=' /etc/wsl.conf | awk -F '=' '{print $2}' | tr -d ' ')
fi
# 設定がtrueの場合に関数を実行
if [ "$append_path_enabled" == "true" ]; then
append_windows_path
fi
どうしてこうなった?
WSL2の連携機能とenv-update
の食い合わせが悪いんです。
PATHの設定が/etc/env.d/50baselayout
にあり、こいつにうまく手を入れて/etc/profile.env
上のPATH
がそれまでのPATH
を読み込むようにすれば起動時にWSL2から受け取るPATH
と統合できると思われるのですが、書き換えてもenv-update
は書かれた文言をシングルクォーテーションで書いてしまうんですよね。
一応、出てきた/etc/profile.env
のシングルクォーテーションをダブルクオーテーションに書き換えるとWSL2が仕事していないわけではないことが理解できます。
とはいえ、ダブルクォーテーションで安定させようとしてenv-update
のそういう設定を仮に発見したとして、emerge
コマンド等がsource /etc/profile
を要求してくるので;$PATH
が付いていると$PATH
がどんどん長くなりそうです。……筋が悪い。
そこでCopilotに相談したところ出てきたのがこのスクリプトで、Windows上のPowerShellを直接呼び出して環境変数を取り出します。
当初はさっぱりWindowsのままのPATHを生のまま接続して空白まみれにしたり、空白を全部セミコロンに置き換えてしまってProgram;Files
ってなっていたりシステム環境変数しか読んでなくてユーザーインストールしたVSCodeが呼べなくて何のために手間かけとんじゃってなったり、Cドライブ前提のsed
が出てきてたりしていましたが、都度修正させて最後はThink Deeper兄貴にブラッシュアップして頂きました。
納得いっていない点
本当はWSL2自身が持っているWindowsのPATH
を呼び出してくる仕組みを直接実行したいのですが、所在がわからないのでできずにいます。
また、appendWindowsPath
が[interop]
以外に書かれていても認識してしまいます。ここをチェックする仕組みもCopilotに書かせたりしたのですが、結構長くなったしそもそも/etc/wsl.conf
を書くのは自分自身なのでとりあえず後回しにしています。