Linuxを学び始めると、こういった疑問にぶつかります。
この2つの違いを理解しておかないと、シェルスクリプトが思ったように動かなかったり、
設定したはずの変数が別のシェルから参照できないといったトラブルに悩まされます。
この記事では、シェル変数と環境変数の違いを実際の動作で確認しながら解説します。
export コマンドの仕組み、env/printenv/set の使い分け、
そして RHEL9 / Rocky Linux 9 での実践的な設定方法まで網羅します。
この記事のポイント
・シェル変数は定義したシェル内だけ有効、環境変数は子プロセスにも引き継がれる
・export 変数名 または export 変数名=値 で環境変数に昇格できる
・env/printenv は環境変数のみ、set はシェル変数と環境変数の両方を表示
・子プロセスでの変更は親プロセスに反映されない(一方向の継承)
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
シェル変数と環境変数の違いとは
Linuxのシェルでは、ユーザーのホームディレクトリやログイン名など、さまざまな情報を 変数 に保存して管理しています。
変数は 有効範囲(スコープ) によって2種類に分けられます。
| 種類 | 有効範囲 | 子プロセスへの継承 |
|---|---|---|
| シェル変数 | 定義したシェル内のみ | されない |
| 環境変数 | 定義したシェル + そのシェルが起動したプログラム(子プロセス) | される |
シェル変数を export コマンドでエクスポート することで、環境変数に昇格できます。
イメージとしては、シェル変数が「ローカル変数」、環境変数が「グローバル変数」に相当します。
シェル変数と環境変数の動作確認
実際に動作を確認してみましょう。以下の手順をターミナルで試してください。1. 変数の定義と確認
$ EV=world ← 変数EVにworldを代入(最初はシェル変数) $ SV=local ← 変数SVにlocalを代入(シェル変数) $ export EV ← exportコマンドでEVを環境変数に昇格
2. 子プロセスからの参照
bash コマンドで新しいシェル(子プロセス)を起動し、変数を参照してみます。$ bash ← 新しいシェル(子プロセス)を起動 $ echo $EV ← 環境変数EVの内容を表示 world ← 環境変数は子プロセスから参照できる $ echo $SV ← シェル変数SVの内容を参照 ← 空白:シェル変数は子プロセスから参照できない
3. 子プロセスでの変更は親に反映されない
$ EV='new world' ← 子プロセスで環境変数EVを再定義 $ exit ← 子プロセスを終了して元のシェルに戻る exit $ echo $EV ← 親シェルのEVを確認 world ← 子プロセスでの変更は反映されない(一方向の継承)
子プロセスで変更した内容が親プロセスに逆伝播することはありません。
変数の定義・参照・削除の基本操作
1. 変数の定義
変数を定義する書式は次の通りです。変数名=値
・「=」の前後にスペースを入れてはいけない(スペースがあるとエラーになる)
・変数名に使えるのは英字・数字・アンダーバー(_)のみ
・変数名の先頭に数字は使えない
・大文字と小文字は別文字として区別される(MY_VAR と my_var は別物)
スペースを含む値を代入する場合は引用符で囲みます。
$ MSG="Hello World" ← ダブルクォートでスペース含む値を設定 $ MSG2='Hello World' ← シングルクォートも可 # 引用符なしでスペースを含む値を設定しようとするとエラーになる $ MSG=Hello World bash: World: command not found
2. 変数の参照(echo コマンド)
定義した変数を参照するには、変数名の先頭に $ を付けて echo コマンドで表示します。$ cp='copy' $ echo $cp copy $ echo "コピー先: $cp" ← ダブルクォート内で変数展開される コピー先: copy $ echo 'コピー先: $cp' ← シングルクォート内では変数展開されない コピー先: $cp
3. 変数の削除(unset コマンド)
変数を削除するには unset コマンドを使います。unset を実行する際は変数名の先頭に $ を付けないことに注意してください。
$ cp='copy' $ echo $cp copy $ unset cp ← $ は付けない $ echo $cp ← 空白:変数が削除されている
export コマンドでシェル変数を環境変数にする
1. export の使い方
シェル変数を環境変数に昇格させるには export コマンドを使います。# 書式1: 既存の変数をエクスポート export 変数名 # 書式2: 定義と同時にエクスポート(1行で書く場合) export 変数名=値
$ MY_VAR="test value" ← シェル変数として定義 $ export MY_VAR ← 環境変数に昇格 # または1行で書く $ export MY_VAR="test value"
2. 環境変数の定義確認
変数が環境変数になっているかどうかは export -p コマンドで確認できます。[pakira@rocky9 ~]$ MY_VAR="test value" [pakira@rocky9 ~]$ export MY_VAR [pakira@rocky9 ~]$ export -p | grep MY_VAR declare -x MY_VAR="test value" # declare -x が付いていれば環境変数として登録されている
env・printenv・set の使い分け
現在定義されている変数を確認するコマンドは3つあります。用途に応じて使い分けましょう。1. env コマンド(環境変数のみ)
env コマンドは現在の環境変数の一覧を表示します。$ env HOME=/home/pakira HOSTNAME=rocky9.example.com LANG=ja_JP.UTF-8 LOGNAME=pakira PATH=/home/pakira/.local/bin:/home/pakira/bin:/usr/local/bin:/usr/bin PWD=/home/pakira SHELL=/bin/bash TERM=xterm-256color USER=pakira ... (以下省略)
2. printenv コマンド(特定の環境変数を表示)
printenv コマンドは特定の環境変数の値だけを表示する場合に便利です。$ printenv PATH /home/pakira/.local/bin:/home/pakira/bin:/usr/local/bin:/usr/bin $ printenv HOME /home/pakira $ printenv LANG ja_JP.UTF-8
3. set コマンド(シェル変数+環境変数を全表示)
set コマンドはシェル変数と環境変数の両方(さらにシェル関数も含む)を全て表示します。出力が大量になるので、grep でフィルタリングするのが実用的です。
$ set | grep MY_VAR MY_VAR='test value' # シェル変数もここで確認できる
よく使われる環境変数の一覧
Linuxで標準的に使われる主要な環境変数を整理します。| 環境変数 | 内容 | 確認コマンド |
|---|---|---|
| PATH | コマンドを検索するディレクトリのリスト | echo $PATH |
| HOME | カレントユーザーのホームディレクトリ | echo $HOME |
| USER | 現在のユーザー名 | echo $USER |
| LOGNAME | ログインシェルのユーザー名 | echo $LOGNAME |
| HOSTNAME | ホスト名 | echo $HOSTNAME |
| LANG | ロケール(言語処理方式) | echo $LANG |
| PWD | カレントディレクトリ | echo $PWD |
| SHELL | ログインシェルのパス | echo $SHELL |
| PS1 | プロンプトの表示文字列 | echo $PS1 |
| HISTSIZE | コマンド履歴の最大保持件数 | echo $HISTSIZE |
| TERM | 端末の種類 | echo $TERM |
実務でよく使うパターン
1. シェルスクリプト内で環境変数を使う
シェルスクリプトは別プロセスとして実行されます。スクリプト内から呼び出し元シェルのシェル変数は参照できませんが、環境変数は参照できます。
# 呼び出し元シェルでの操作 $ export DB_HOST="db.example.com" ← 環境変数としてエクスポート $ export DB_USER="pakira" # スクリプト内での参照 #!/bin/bash echo "DB host: $DB_HOST" ← 環境変数は参照できる echo "DB user: $DB_USER"
2. 一時的な環境変数でコマンドを実行する
コマンドの前に 変数名=値 コマンド の形式で記述すると、そのコマンドの実行中だけ有効な一時的な環境変数を設定できます。
# LANG=C を一時的に設定してコマンドを実行(日本語でなく英語でエラー表示) $ LANG=C ls /nonexistent ls: cannot access '/nonexistent': No such file or directory # 通常の ls では日本語でエラーが出るが、LANG=C にすると英語になる $ echo $LANG ja_JP.UTF-8 # 元の設定には影響しない
トラブルシュート:変数が反映されない場合
シェル変数のつもりが環境変数になっていない(またはその逆)
# 確認方法 $ export -p | grep 変数名 # 何も表示されない → シェル変数(環境変数ではない) # declare -x が表示される → 環境変数として登録済み
スクリプトを実行したが変数が設定されない
スクリプトを通常実行(./script.sh)すると子プロセスとして実行されるため、スクリプト内で定義した変数は呼び出し元に反映されません。
呼び出し元のシェルに変数を反映させたい場合は source コマンド(または .)を使います。
# 通常実行(子プロセス → 変数は呼び出し元に反映されない) $ ./setup.sh # sourceで実行(現在のシェルで実行 → 変数が反映される) $ source setup.sh # または $ . setup.sh
ダブルクォートとシングルクォートの違いでハマる
$ NAME="pakira" $ echo "Hello $NAME" ← ダブルクォート:変数が展開される Hello pakira $ echo 'Hello $NAME' ← シングルクォート:変数展開されない Hello $NAME
本記事のまとめ
| 操作 | コマンド |
|---|---|
| シェル変数を定義 | 変数名=値 |
| 環境変数に昇格(既存変数) | export 変数名 |
| 環境変数として定義(1行) | export 変数名=値 |
| 変数の参照 | echo $変数名 |
| 変数の削除 | unset 変数名 |
| 環境変数の一覧表示 | env または printenv |
| シェル変数+環境変数の全表示 | set |
| 特定の環境変数を確認 | printenv 変数名 |
| 環境変数の登録確認 | export -p | grep 変数名 |
シェル変数と環境変数の違いを理解することは、
シェルスクリプト作成やサーバー設定作業の土台となります。
「変数が引き継がれない」「スクリプトで設定したのに反映されない」というトラブルのほとんどは、
この仕組みを理解していれば防げます。
環境変数PATHの設定方法については環境変数PATHの設定方法も合わせて参照してください。
変数を活用したシェルスクリプトの書き方はシェルスクリプトの基礎で詳しく解説しています。
Linuxの基礎から実務スキルを身につけたい方へ
シェル変数・環境変数のような基礎概念を正しく理解した上で、実務レベルのサーバー運用に進むのが最短ルートです。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、「Linuxサーバー構築入門マニュアル(図解60P)」を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます