できない.dev

Bash で PATH に追加したのに command not found が消えない

.bashrcexport PATH=... を書いても効かないのは、そのシェルがどの起動ファイルを読むかが起動の種類で違うためである。
対話ログインシェルは .bash_profile 系を読み、対話非ログインシェルは .bashrc を読む。

公開: 更新:

要約

PATH を通したはずなのに command not found が消えないとき、設定内容ではなく 書いたファイルがそのシェルで読まれていない ことがほとんどである。
Bash はシェルの種類によって読む起動ファイルを変える。

$ echo $PATH
/usr/local/bin:/usr/bin:/bin      # 追加したはずの ~/.local/bin が無い
$ grep PATH ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"   # 書いてはある

書いた場所は合っているのに反映されない、という状態である。
まずどの起動ファイルが読まれるシェルなのかを確かめる。

よくある原因

  1. ログインシェルは .bashrc を読まない: Bash Startup Files(新しいタブで開く) のとおり、対話ログインシェルは /etc/profile を読んだあと ~/.bash_profile~/.bash_login~/.profile をこの順に探し、最初に見つかった 1 つだけを読む。
    対話非ログインシェルが読むのは ~/.bashrc である。
  2. .bash_profile.profile を潰している: .profile に書いたのに効かない場合、.bash_profile が存在していてそちらが優先されている。
  3. 反映していない: ファイルを編集しただけでは現在のシェルの PATH は変わらない。
  4. export を忘れた: PATH=... だけではシェル変数にとどまり、そこから起動したコマンドには渡らない。
  5. 非対話シェル: cron や CI のステップはどの起動ファイルも読まないため、対話シェルでは通るのにジョブでは落ちる。

解決策

1. .bashrc に書き、.bash_profile から読ませる

# ~/.bash_profile
[ -f ~/.bashrc ] && . ~/.bashrc
# ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"

設定の実体は .bashrc に一本化し、.bash_profile は橋渡しだけにする。
こうするとログイン・非ログインのどちらでも同じ PATH になる。

2. 現在のシェルに反映する

source ~/.bashrc
echo $PATH

新しいターミナルを開き直しても同じ結果になる。

3. どこから引かれているかを見る

type -a python3

複数出るときは上に出たものが実際に使われる。
意図しないパスが先勝ちしているなら、追記の順序($PATH の前に置くか後ろに置くか)を見直す。

この記事は役立ちましたか?