Linuxやbashを使っていると、exportコマンドに出会う機会が必ずあります。しかし「なぜexportが必要なのか」「シェル変数と環境変数は何が違うのか」を正確に理解している人は意外と少ないです。
この記事では、exportコマンドの意味から、シェル変数と環境変数の違い、子プロセスへの引き継ぎの仕組み、確認・削除・永続化の方法まで、順序立てて解説します。
exportコマンドとは
exportは、シェル変数を「環境変数」として子プロセスに引き継ぐためのbash組み込みコマンドです。
シェルで変数を定義しただけでは、その変数は現在のシェルセッション内でしか使えません。exportを付けることで、その変数が子プロセス(サブシェルや実行したコマンド)にも自動的に渡されるようになります。
シェル変数と環境変数の違い
Bashの変数には大きく2種類あります。
| 種類 | 定義方法 | 子プロセスに引き継がれるか |
|---|---|---|
| シェル変数 | VAR=value |
引き継がれない |
| 環境変数 | export VAR=value |
引き継がれる |
シェル変数は現在のシェルプロセス内だけで有効です。環境変数は、そのシェルから起動した子プロセスにも渡されます。
実例で確認する
# シェル変数(exportなし)
SHELL_VAR="hello"
bash -c 'echo $SHELL_VAR' # 出力なし(子プロセスに渡らない)
# 環境変数(exportあり)
export ENV_VAR="world"
bash -c 'echo $ENV_VAR' # world(子プロセスに渡る)
bash -c '...'は新しいbashプロセス(子プロセス)を起動して、その中でコマンドを実行します。exportした変数だけが子プロセスに渡ることが確認できます。
基本の使い方
export VAR=value(変数の定義とエクスポートを同時に行う)
export MY_APP="myapp"
変数の定義とエクスポートを1行で行う、最もよく使われる書き方です。
VAR=value → export VAR(後からエクスポートする)
MY_APP="myapp"
export MY_APP
先に変数を定義しておき、後からexportでエクスポートする書き方です。スクリプト内で値を計算してからエクスポートしたい場合に使います。
export VAR(すでに設定された変数をエクスポートする)
MY_APP="myapp"
# ...何らかの処理...
export MY_APP # 値はそのままでエクスポートフラグを付ける
子プロセスへの引き継ぎの仕組み
Linuxでプロセスが新しいプロセスを起動すると、親プロセスの環境変数が子プロセスにコピーされます。これはOSレベルの仕組みです。
export APP_ENV="production"
# bashスクリプト内でも参照できる
./deploy.sh # deploy.sh の中で $APP_ENV を使える
# 子プロセスのさらに子プロセスにも渡る
bash -c 'bash -c "echo $APP_ENV"' # production
ただし、子プロセスが環境変数を変更しても、親プロセスの変数には影響しません。コピーが渡されるためです。
環境変数を確認する方法
printenv:環境変数のみを表示する
# すべての環境変数を表示
printenv
# 特定の変数を確認
printenv MY_APP
printenvはエクスポートされた環境変数だけを表示します。シェル変数(exportなし)は表示されません。
env:環境変数の一覧表示・コマンド実行
# 現在の環境変数をすべて表示
env
# 特定の環境変数だけを設定してコマンドを実行
env APP_ENV=staging ./deploy.sh
echo $VAR:特定の変数の値を確認
echo $MY_APP # myapp
echo ${MY_APP} # myapp(波括弧付き、文字連結時に便利)
declare -x:exportされた変数の一覧を表示
declare -x
# 出力例: declare -x MY_APP="myapp"
declare -xはエクスポートされたすべての変数を確認できます。シェル変数との区別が明確になります。
環境変数を削除する方法
不要になった環境変数はunsetで削除できます。
export MY_APP="myapp"
echo $MY_APP # myapp
unset MY_APP
echo $MY_APP # 空白(変数が存在しない)
unsetはシェル変数・環境変数のどちらにも使えます。削除後はprintenv MY_APPで何も出力されなくなります。
PATHに追加する方法
独自のツールやスクリプトをどこからでも実行できるようにするには、PATHに追加します。
# 既存のPATHを維持しつつ追加する
export PATH="$PATH:/path/to/bin"
# 例:~/binを追加する
export PATH="$PATH:$HOME/bin"
"$PATH:/path/to/bin"と書くことで、既存のパスを保ちつつ新しいパスを追加できます。$PATHを省略すると既存のパスがすべて消えてしまうので注意してください。
一時的な設定と永続化の違い
ターミナルでexportした変数は、そのシェルセッションが終わると消えます。再起動後も残すには、シェルの初期化ファイルに書く必要があります。
.bashrcと.bash_profileの違い
| ファイル | 読み込まれるタイミング | 主な用途 |
|---|---|---|
~/.bashrc |
インタラクティブな非ログインシェル起動時 | エイリアス・関数・環境変数 |
~/.bash_profile |
ログインシェル起動時(SSH・コンソールログイン) | 環境変数・PATH設定 |
~/.profile |
ログインシェル起動時(bash以外も読む) | POSIXシェル共通の設定 |
一般的なデスクトップ環境では~/.bashrcに書くのが最もシンプルです。サーバーのSSH接続では~/.bash_profileから~/.bashrcを読み込む設定になっていることが多いです。
.bashrcへの追記例
# ~/.bashrc に追記
export JAVA_HOME="/usr/lib/jvm/java-17"
export PATH="$PATH:$JAVA_HOME/bin"
export APP_ENV="development"
追記後、現在のシェルに反映するにはsourceコマンドを使います。
source ~/.bashrc
# または省略形
. ~/.bashrc
シェルスクリプト内でexportを使う
シェルスクリプト内でもexportを使えます。スクリプトから呼び出す別のスクリプトや外部コマンドに変数を渡したい場合に使います。
#!/bin/bash
export DB_HOST="localhost"
export DB_PORT="5432"
export DB_NAME="mydb"
# 同じスクリプトから呼び出すコマンドに環境変数が渡る
./run-migration.sh
node app.js
注意:スクリプトを./script.shで実行した場合、スクリプト内のexportは子プロセス(スクリプトのシェル)内だけで有効です。親シェルには影響しません。
スクリプトで定義した変数を親シェルに引き継がせたい場合は、source(または.)で実行します。
source ./setup-env.sh # 親シェルで実行されるので、変数が引き継がれる
. ./setup-env.sh # 同じ意味
よくある失敗例
= の前後にスペースを入れてしまう
# NG:スペースを入れると代入にならない
export VAR = "value" # エラー: 「=: not found」など
# OK
export VAR="value"
永続化したつもりで現在のシェルしか反映されていない
# ターミナルで実行しても ~/.bashrc に書いても同じ変数名なら混乱する
export MY_VAR="temp" # これはセッション限り
# ~/.bashrc に書いても、source しないと現在のシェルには反映されない
echo 'export MY_VAR="persistent"' >> ~/.bashrc
# ↑ この時点ではまだ MY_VAR="temp" のまま
source ~/.bashrc # ← これを忘れずに
子プロセスへの引き継ぎ範囲の誤解
export MY_VAR="hello"
bash -c 'MY_VAR="changed"; echo $MY_VAR' # changed(子プロセス内)
echo $MY_VAR # hello(親シェルは変わらない)
子プロセスで変数を変更しても、親シェルの変数は変わりません。子プロセスに渡るのはあくまでコピーです。
$PATHを上書きしてしまう
# NG:既存のPATHが消える
export PATH="/my/bin"
# OK:既存のPATHを維持して追加
export PATH="$PATH:/my/bin"
PATHを誤って上書きすると、lsやcdなどの基本コマンドも実行できなくなります。
よくある疑問
exportは何をするコマンドか
シェル変数に「エクスポートフラグ」を付けるコマンドです。フラグが付いた変数は環境変数として子プロセスに渡されます。
VAR=valueとexport VAR=valueは何が違うか
VAR=valueはシェル変数として現在のシェルにのみ存在します。export VAR=valueは環境変数として子プロセスにも引き継がれます。printenvで確認した場合、後者だけが表示されます。
exportした値はどこまで有効か
現在のシェルセッションと、そこから起動したすべての子プロセス(孫プロセスも含む)で有効です。ただし、親シェルには遡って影響しません。セッションを閉じると消えます。
再起動後も残すにはどうするか
~/.bashrc(または~/.bash_profile)にexport VAR=valueを追記します。次回のシェル起動時に自動的に読み込まれます。
環境変数を削除するにはどうするか
unset VARで削除できます。export -n VARはエクスポートフラグだけを外し、シェル変数として残します。
export MY_VAR="hello"
export -n MY_VAR # エクスポートフラグを外す(シェル変数として残る)
unset MY_VAR # 変数ごと削除する
まとめ
exportコマンドは、シェル変数を環境変数として子プロセスに引き継ぐための仕組みです。以下のポイントを押さえておきましょう。
VAR=valueはシェル変数、export VAR=valueは環境変数- 環境変数は子プロセス(サブシェル・外部コマンド)に自動的に渡される
printenvやenvで環境変数を確認できるunset VARで変数を削除できる- 永続化するには
~/.bashrcや~/.bash_profileに書いてsourceする - PATHを追加するときは
export PATH="$PATH:/path/to/bin"の形で既存パスを維持する

コメント