シェル環境変数 - export・env・.bashrc・.bash_profile

シェル環境変数 - export・env・.bashrc・.bash_profile

この記事で達成できること

  • シェル変数と環境変数の違いを子プロセス継承の観点で説明できる
  • export がなぜ必要かを正確に理解できる
  • ログインシェルと非ログインシェルの起動ファイル読み込み順序を説明できる
  • .bashrc.bash_profile を用途に応じて正しく使い分けられる
  • 設定変更が反映されない原因を特定できる

LPIC-1 主題 105.1「シェル環境のカスタマイズと使用」の中核。環境変数の継承モデルと起動ファイルの読み込み順序が要点。

シェル変数と環境変数の判断

観点 シェル変数 環境変数
設定方法 VAR=value export VAR=value
子プロセスへの継承 されない される
一覧表示 set env / printenv
用途 現在のシェル内の一時値 子プロセスに渡す設定(PATH 等)

子プロセス(実行したコマンド・スクリプト)に値を渡す必要があるなら export で環境変数にする。シェル内だけの一時計算ならシェル変数で十分。

起動ファイルの読み込み順序

シェル種別 読み込まれるファイル
ログインシェル /etc/profile~/.bash_profile(なければ ~/.bash_login~/.profile
非ログイン対話シェル /etc/bash.bashrc~/.bashrc
非対話シェル(スクリプト) $BASH_ENV が指すファイル(通常なし)

慣例として ~/.bash_profile 内で ~/.bashrcsource し、設定を ~/.bashrc に集約するのが定石。これを知らないと「SSH ログインでは反映されるが端末を開くと反映されない(またはその逆)」を説明できない。

手順

Step 1: シェル変数を設定し継承を確認する

MYVAR=hello
echo $MYVAR
bash -c 'echo "child sees: $MYVAR"'
hello
child sees:

MYVAR はシェル変数なので子プロセス(bash -c)には継承されず空になる。これが環境変数との決定的な違い。

Step 2: export で環境変数に昇格する

export MYVAR
bash -c 'echo "child sees: $MYVAR"'
export GREETING=hi
env | grep GREETING
child sees: hello
GREETING=hi

export でシェル変数を環境変数に昇格すると子プロセスに継承される。export VAR=value で設定と昇格を同時に行える。

Step 3: 変数一覧を確認する

set | grep MYVAR
env | grep MYVAR
printenv PATH
MYVAR=hello
MYVAR=hello
/usr/local/bin:/usr/bin:/bin

set はシェル変数を含む全変数、envprintenv)は環境変数のみを表示する。両方に出るなら export 済み、set にだけ出るならシェル変数のまま。

Step 4: 起動ファイルを編集して反映する

echo 'export EDITOR=vim' >> ~/.bashrc
echo "alias ll='ls -alF'" >> ~/.bashrc
source ~/.bashrc
echo $EDITOR
vim

.bashrc への追記は新規シェルから有効になる。現在のシェルに即座に反映するには source ~/.bashrc. ~/.bashrc と等価)を実行する。

Step 5: 変数を削除する

unset MYVAR
echo "[$MYVAR]"
unalias ll
[]

unset は変数を削除する。エイリアスは unalias で解除する。一時的に環境変数なしでコマンドを実行するには env -u VAR command も使える。

なぜ export が必要なのか

Linux のプロセスは fork + exec で子プロセスを生成する。このとき親プロセスの「環境(environment)」だけが子にコピーされ、シェル変数は子のメモリ空間に渡されない。export は変数に「環境としてエクスポートする」属性を付与する操作であり、これにより exec 時に子プロセスの環境に含まれるようになる。

PATHLANG が子プロセスでも有効なのは、それらがログイン時に export 済みの環境変数だから。逆に export していないシェル変数をスクリプトから参照できないのは、スクリプトが子プロセスとして起動され環境を継承するこのモデルが原因。継承は親→子の一方向で、子で変更した環境変数が親に戻ることはない。

トラブルシューティング

症状: .bashrc の変更が SSH ログインで反映されない

原因: SSH ログインはログインシェルで、~/.bashrc ではなく ~/.bash_profile が読まれる

確認:

grep bashrc ~/.bash_profile

対処: ~/.bash_profile[ -f ~/.bashrc ] && . ~/.bashrc を追加し、設定を ~/.bashrc に集約する。

症状: スクリプトから変数が見えない

原因: シェル変数のまま export していない

確認:

export -p | grep VAR

対処: 子プロセス(スクリプト)に渡す変数は export VAR で環境変数に昇格する。

症状: source せず変数が反映されない

原因: 起動ファイルへの追記は新規シェルからしか有効にならない

確認:

echo $EDITOR

対処: 現在のシェルに即時反映するには source ~/.bashrc を実行する。新しい端末を開いても反映される。

作業完了チェックリスト

  • [ ] シェル変数が子プロセスに継承されないことを確認した
  • [ ] export 後に子プロセスへ継承されることを確認した
  • [ ] setenv の表示差を確認した
  • [ ] .bashrc を編集し source で即時反映した
  • [ ] unset で変数を削除した

まとめ

場面 コマンド 目的
シェル変数 VAR=value 現在のシェル内の一時値
環境変数昇格 export VAR 子プロセスへ継承
一覧(環境) env / printenv 環境変数の確認
一覧(全体) set シェル変数も含む
即時反映 source ~/.bashrc 起動ファイル再読込

環境変数モデルはプロセス継承の理解に直結する。次はプロセス優先度の制御に進むと運用知識が連結する。

次に読む