PATH変数とは何か? shellがプログラムを見つける場所
PATHは、入力したコマンドの背後にあるプログラムを見つけるためにshellが順に検索するディレクトリのリストを保持する環境変数です。
nodeやpytestと入力するとき、shellはそのプログラムがどこにあるかを魔法のように知っているわけではありません。PATH変数にリストされたディレクトリを左から右へたどり、最初に見つかった一致する実行ファイルを実行します。誤って設定されたPATHは、CI stepが「command not found」で死ぬ最も一般的な理由の1つです。
PATHの仕組み
PATHはコロン区切りのディレクトリのリストです (Windowsではセミコロン区切り)。各裸のコマンド名に対して、shellは各ディレクトリを順にチェックし、一致する最初の実行ファイルを実行します。どれも一致しなければ「command not found」となります。
PATHの読み取りと変更
echo "$PATH"で表示できます。ディレクトリを追加するには、先頭または末尾に付け、通常はexport PATH="/new/dir:$PATH"と書きます。先頭に付けると自分のディレクトリがシステムのものより優先され、末尾に付けるとフォールバックになります。
なぜ順序が重要か
- 最初の一致が勝つので、先のディレクトリが後のものを覆い隠す。
- ツールのディレクトリを先頭に付けると、システムのバージョンを上書きできる。
- 重複したまたは誤ったエントリは、静かに誤ったバイナリを実行しうる。
CIでのPATH
CIランナーは、インストールされたtoolchainに到達できるようPATHを設定します。ツールをカスタムの場所にインストールするときは、後続のstepが見つけられるようにPATHに追加しなければなりません。さもなければ、インストールが成功しても、jobは「command not found」で失敗します。
step間でのPATHの永続化
GitHub Actionsでは、1つのrun: stepでPATHをexportしても次には引き継がれません。各stepが新しいshellだからです。代わりにディレクトリを特別な$GITHUB_PATHファイルに追記し、それにより後続のすべてのstepで利用可能になります。
管理型ランナーでのPATH
Latchkeyのランナーは一般的なtoolchainをすでにPATHに含んでいるので、ほとんどのjobは設定なしでツールを見つけます。jobの途中でインストールするカスタムバイナリについては、PATHの変更は永続化しない限りstep単位であることを覚えておいてください。
重要なポイント
- PATHは、コマンド名を解決するためにshellが検索するディレクトリをリストします。
- 最初に一致した実行ファイルが勝つので、ディレクトリの順序がどのバイナリを実行するか決めます。
- CIでは、誤ったまたは永続化されないPATHが「command not found」の主要な原因です。