まず結論
- ちゃんと使い分けた方がいい。具体的な使い分けはこの記事参照 https://qiita.com/magicant/items/d3bb7ea1192e63fba850
- ただ、全部profileでも、実害が出ない場合が多く、タイトルのような勘違いが起こる
- 人が納得するには、それが「何か」だけでなく、「何のため(意義)」も理解しないといけない
想定読者
- 基本的なシェルコマンドの知識がある
- profile(
.bash_profile
とか.zprofile
)とrc(.bashrc
とか.zshrc
)の使い分けについて調べてなんとなく理解しているが、そもそも使い分ける意義がわからない。「結局全部profileでいいじゃん」状態の人
背景
自分はエンジニア志望の学生で、2年ほどプログラムを学んできたが、これまでずっとrcファイルをつかわず、全部profileに書いていた。
まさに、上の想定読者の状態だった。なんとなく、使い分けの記事(https://qiita.com/magicant/items/d3bb7ea1192e63fba850) とかを読んで、aliasはrc、環境変数はprofileっていう作法なのか、、、くらいに思っていたが、全部profileに書いても特に支障がなかったため、面倒臭くて全部profileに書いていた。
環境
- OS:mac OS Monterey version 12.2.1
- チップ:Apple M1
- シェル:zsh
前提知識
profile
- シェルにログインしたときに一度だけ読み込まれる
- ターミナル、power shellなどを起動したとき、新規ウィンドウで複数起動したときなど
rc
- シェルを起動するたびに読み込まれる
- 上記のprofile読み込みのタイミングに加え、手動でシェルを起動したとき(コマンドで
bash
やzsh
を起動したとき)など
shellにおける、export
の振る舞いと他との違い
- 環境変数を定めたりできる
- これで定義されたものは、一度読み込まれれば他のシェルにも引き継がれる
- 一方、シェル変数やaliasなどのその他は、基本的に定義されたシェルにおいてのみ有効。別のシェルには引き継がれない
「全部profile」で生じる問題
=直接シェルを呼び出したときなどに、別シェルに引き継がれないもの(aliasなど)が読み込めない。
以下、aliasをprofileに書いた場合とrcファイルに書いた場合を比較
aliasをprofile(~/.zprofile
)に記述した場合
- 環境
% cat ~/.zprofile
export TEST_ENV='This is a test environmental var!'
alias test_alias="echo 'This is a test alias!'"
- ターミナル(windowsならpower shellとか)の新規ウィンドウでシェルを起動したとき(シェルに再ログイン)
% echo $TEST_ENV
This is a test environmental var!
%
% test_alias
This is a test alias!
- シェルを手動で起動した場合(=シェルへの再ログインを経ていない)
% zsh #以降、手動で起動した、子プロセスである別のzshの上で実行されている
%
% echo $TEST_ENV
This is a test environmental var!
%
% test_alias
zsh: command not found: test_alias #profileのalias定義が反映されていない
- 考察
=手動でシェルを起動したときなど、ログインを経ずにシェルを起動した場合は、profileが読み込まれず、aliasのような、別のシェルに引き継がれないものは反映されない。(環境変数は、一度読み込まれれば、他のシェルに引き継がれるため、再ログインせずとも反映される)
aliasをrcファイル(.zshrc
)に記述した場合
- 環境
% cat ~/.zprofile
export TEST_ENV='This is a test environmental var!'
%
% cat ~/.zshrc
alias test_alias="echo 'This is a test alias!'"
- ターミナル(windowsならpower shellとか)の新規ウィンドウでシェルを起動したとき(シェルにログイン)
% echo $TEST_ENV
This is a test environmental var!
%
% test_alias
This is a test alias!
- シェルを手動で起動した場合(=シェルへのログインを経ていない)
% zsh #以降、手動で起動した、子プロセスである別のzshの上で実行されている
%
% echo $TEST_ENV
This is a test environmental var!
%
% test_alias
This is a test alias! #ちゃんとaliasが読み込まれている
- 考察
=今回は、rcファイルにalias定義を記述したため、zshをログインを経ずに手動で起動したときにも、rcファイルが読み込まれることで、alias定義が反映された
なぜこの問題に気づきにくいのか = なぜ「とりあえず全部profileでok」と思われがちか
- 少なくとも、自分のような1,2年目の学習者が、手動でシェルを起動するなど、ログインを経ずにシェルを起動しなくてはいけないときがほとんどない
- シェルを複数開きたいときも、新規ウィンドウで開くなどするため、無意識に再ログインしており、その度にprofileが読み込まれるため、aliasなどをprofileに書いていても問題なく反映されてしまう
結局、全部profileは本当にダメなのか
- 正直、絶対ダメではない、というのが現段階の自分の結論。ログインを経ずにシェル起動する場面が特に思いつかない。ただ、問題が生じうる構造をわざわざ作る必要もない
- 別途rcファイルを用意して、alias定義などの別シェルに引き継がれないものをrcファイルに移すのは大したコストではないので、基本はrcファイルをつくってprofileと使い分けるべき(環境変数はprofile、それ以外はrc。詳しい使い分けは別記事参照)
余談: 人の納得について
塾講師で数学の定理を生徒に教えるときに自分が意識していたことだが、その定理が何を指しているのかや成り立ち(証明)だけでなく、そもそもこの定理を使うことの意義、有用性(こういう図形問題解ける、、、とか)をちゃんと説明するようにしていた。後者がないときの生徒の反応はかなり微妙だった
今回の自分も、 profileとrcの使い分け自体は知識として何となく知っていても、自分の手元の環境で、使い分けてなくても一見差分がなかったために、使い分けることに納得できていなかった。しないと問題が生じうる、あるいは実施するとこんなメリットがある、という面も含めて「納得」なのだと思う。