夜中にしょーーーーーもない罠にハマってしまったので、メモしておく。
環境
OS : Amazon Linux AMI release 2017.09
bash : GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
.bashrcやら.bash_profileやらの実行順序
正解はここらへんに。先人の記事を引用
http://oxynotes.com/?p=5418
https://qiita.com/yunzeroin/items/480a3a677f78a57ac52f
この記事のために端的に説明すると、.bash_profileが先、.bashrcがあと。
引っかかった罠
.bash_profileが先で、どうやらexportするPATHとかはこっちに書いておくのがいいっぽい?
とはいえ、ログイン時も対話実行時もどちらも結局ユーザの~/.bashrcが読み込まれるんだから、こちらに集約したほうがいいような気もするけど、ここらへんの正解はよくわかってない。
http://neos21.hatenablog.com/entry/2017/02/12/142817
https://qiita.com/magicant/items/d3bb7ea1192e63fba850
上記のような記事をみて、あー、環境変数は.bash_profileに書いたほうがいいのかなーと思い、これまで.bashrcに定義していた環境変数を.bash_profileに移植してみる。すると。
現れた問題
-bash: pyenv: command not found
-bash: pyenv: command not found
シェルログイン時に実行してるpyenvがcommand not foundに。
実行しているコマンドは、.bashrcに記載されたコレ
# pyenv
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
で、シェルログイン後に改めてpyenvをたたくと、ちゃんとpyenvは認識されている。
$ pyenv --version
pyenv 1.2.3
あれー?パスも通ってるし、.bash_profileが先ならなんで.bashrcのpyenvが動かないんだー?ってことで、よくわからなくなってしまい調査。
調査
.bashrcと.bash_profileの 末尾 に以下のechoを埋めてみる。
# test
echo "bash_profile"
# test
echo "bashrc"
実行順序通りに標準出力にechoされるハズ。すると。
-bash: pyenv: command not found
-bash: pyenv: command not found
bashrc
bash_profile
!!!
bashrcのほうが先に読み込まれてる??あれーそういうもん?
答え
.bash_profileの 先頭 にこんな文字列がありましたとさ。
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
~
~
!!!
.bash_profileの先頭で.bashrc読み込んでるやん!!そのあとにパス通してる部分あるんだから、そりゃそうでしょ!!!というお粗末な結論でした。
ちなみに
.bash_profileが実行されたあとに.bashrcが実行される、というのは、.bash_profileが.bashrcを呼んでいるから、みたい。 .bash_profileに記載された
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
をコメントアウトしたら、そもそも.bashrcは読み込まれなくなった。
bashコマンドでbashを再度呼ぶと読み込まれる。
結び
というわけで、なにが正解なのかはよくわかってないのですが、以下のように運用しようと思いました。
- 環境変数は.bash_profileに書く
- 環境変数以外のシェル変数や関数、aliasなどは.bashrcに書く
- .bashrcの読み込みは、.bash_profileの最後で実行する
詳しい人、正解を教えてください。