環境変数の基礎 - 設定と活用法

環境変数の基礎 - 設定と活用法

この記事でできるようになること

  • `echo $VAR` や `env` で、環境変数の中身を確認できる
  • `export` で環境変数を設定できる。シェル変数との違いも説明できる
  • `PATH` の仕組みを理解して、`command not found` を自力で直せる

前提知識(先に読むと理解しやすい記事)

この記事でできるようになること

対象読者:Linuxの基本コマンド(pwd・cd・ls)は使えるが、$HOMEexport の意味がピンとこない方。

導入:環境変数って何?

リナ: ライニー先輩、教科書に $HOME$PATH がよく出てきます。これは何でしょうか。$ マークが付いていて、呪文みたいです。
ライニー先輩: いいところに気づいたね。それは「環境変数」と呼ばれるものだよ。シェル入力したコマンドを解釈してコンピュータに実行させる対話プログラム。が覚えている「名前付きのメモ書き」 だと考えるといい。
リナ: メモ書き、ですか。
ライニー先輩: そう。冷蔵庫に貼ってある付箋を想像してみて。「牛乳は下の段」と書いた付箋があれば、毎回探さなくて済むよね。
ライニー先輩: 同じように「私のホームディレクトリは /home/lina」という情報を、HOME という名前で覚えてあるんだ。だから $HOME と書けば、その中身が呼び出される。

言葉の整理

  • 変数:値を入れておく名前付きの箱です。名前を書けば、中身を取り出せます。
  • シェル変数:今のシェルの中だけで使える変数です。
  • 環境変数:シェル変数のうち、そこから起動したコマンドにも引き継がれるものです。export を付けると環境変数になります。
  • 子プロセス:あるコマンドから起動された別のコマンドのことです。

つまり「環境変数はシェル変数の一種で、引き継がれる印が付いたもの」です。この違いは 2 章 で実験して確かめます。

結論(実務の型)

  • 中身を見たいだけ → echo $VAR または env | grep VAR
  • 自分のシェルだけで使いたい → export VAR=値
  • 次のログインでも残したい → ~/.bashrc に書く
  • command not found の8割は PATH が原因

前提(対象環境)

1. 環境変数を見てみよう

結論: echo $VAR で 1 つ、env / printenv で全部を確認できる。設定より先に現状を読むのが安全。

ライニー先輩: まずは「読む」ところから。設定するより先に、今何があるかを見るのが安全だよ。

1-1. 1 つの変数を見る:echo $VAR

$ echo $HOME
/home/lina
$ echo $USER
lina

ここがポイント

  • $ を付けると、「変数の中身に置きかえる」という意味になります。この置きかえを「展開」と呼びます。
  • $ を付けずに echo HOME と打つと、ただの文字として「HOME」が表示されます。
  • 変数名は 大文字 にするのが慣例です。必須ではありませんが、揃えると読みやすくなります。
リナ: $ を付けるかどうかで、結果が全然違うんですね。
ライニー先輩: そう。ここが最初のつまずきポイントなんだ。「$ は中身を呼び出すスイッチ」と覚えておけば大丈夫だよ。

1-2. 全部の環境変数を見る:env / printenv

$ env
SHELL=/bin/bash
USER=lina
HOME=/home/lina
PATH=/usr/local/bin:/usr/bin:/bin
LANG=ja_JP.UTF-8
PWD=/home/lina
...

env は、今使える環境変数をすべて表示します。printenv でも同じことができます。

出力が長いときは env | less を使います。1 画面ずつ送れます。特定の変数を探すときは env | grep PATH のように絞り込みます。

1-3. よく見る環境変数

変数名 意味
HOME 自分のホームディレクトリ /home/lina
USER 現在のユーザー名 lina
PATH コマンドを探しに行くディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。 /usr/local/bin:/usr/bin:/bin
SHELL 使っているシェル /bin/bash
LANG 言語・文字コードの設定 ja_JP.UTF-8
PWD 今いるディレクトリ(pwd と同じ) /home/lina/work
リナ: たくさんありますね。全部覚えなければいけませんか。
ライニー先輩: その必要はないよ。ふだん意識するのは HOMEPATH くらい。残りは「そういうのもある」で十分だよ。

2. 自分で設定する:代入と export

結論: 代入だけなら今のシェル限定。export を付けると、子プロセスにも引き継がれる環境変数になる。

ライニー先輩: 次は自分で設定する番だよ。ここには ハマりやすい落とし穴 がある。ゆっくり進めよう。

2-1. ただの代入(シェル変数)

$ MY_NAME=lina
$ echo $MY_NAME
lina

= の両側にスペースを入れないでください。

MY_NAME = lina と書くと、シェルは「MY_NAME というコマンドを実行する」と解釈します。そのためエラーになります。初心者がよく起こす事故です。

2-2. export で「環境変数」に昇格

$ MY_NAME=lina
$ export MY_NAME

または一気に:

$ export MY_NAME=lina
リナ: 代入と export は何が違うのでしょうか。同じに見えます。
ライニー先輩: 大事な質問だね。代入だけだと、そのシェルの中でしか使えないんだ。
ライニー先輩: そこから実行したコマンドやスクリプト、つまり子プロセスには引き継がれない。export を付けると環境変数になって、子プロセスからも見えるようになるよ。

2-3. 違いを実感する実験

$ MY_VAR=hello
$ bash -c 'echo $MY_VAR'

何も表示されず、空行になります。bash -c は新しいシェルを子プロセスとして起動します。そこには MY_VAR が届いていません。

$ export MY_VAR=hello
$ bash -c 'echo $MY_VAR'
hello

今度は表示されました。export を付けたので、子プロセスにも引き継がれたからです。

鉄則: スクリプトや別のコマンドに値を渡したいときは、必ず export を付けます。自分のメモとして使うだけなら = だけでかまいません。

2-4. 変数を消したい

$ unset MY_VAR
$ echo $MY_VAR

unset で変数を削除できます。ただし消えるのは今のシェルの分だけです。

.bashrc に書いた設定は、そのファイルを編集しないかぎり残ります。

3. PATH:一番大事な環境変数

結論: PATH はコマンドを探すディレクトリ群。追加時は :$PATH を末尾に付けないと既存パスファイルやディレクトリの場所を表す文字列。が消える。

リナ: command not found というエラーがよく出ます。これも環境変数と関係があるのでしょうか。
ライニー先輩: 大いに関係あるよ。PATH を理解すれば、そのまま command not found の解決につながる。

3-1. PATH の中身を見る

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ここがポイント

  • PATH の中身は、: で区切られたディレクトリの並びです。
  • コマンドを打つと、シェルは 左から順に これらのディレクトリを探します。
  • 最初に見つかった同じ名前のコマンドが実行されます。

学校の下駄箱に例えると、PATH は「1 組から順に探す」という探し方の指示にあたります。

3-2. 「どこにあるか」を調べる:which

$ which ls
/usr/bin/ls
$ which python3
/usr/bin/python3
リナ: ls/usr/bin/ の中にあるんですね。
ライニー先輩: そう。ls と打つだけで動くのは、PATH/usr/bin が含まれているからだよ。
ライニー先輩: もし PATH から /usr/bin を消したら、/usr/bin/ls とフルパスで打たないと動かなくなる。

3-3. PATH を追加したい(自分のスクリプト置き場)

~/bin を作って、自作スクリプトを置きたい場合を考えます。

$ mkdir -p ~/bin
$ export PATH="$HOME/bin:$PATH"

末尾の :$PATH を必ず付けてください。

export PATH="$HOME/bin" とだけ書くと、既存の PATH が全部消えます。その結果、ほとんどのコマンドが command not found になります。事故が最も多い操作です。

もし消してしまっても、新しいターミナルを開けば元に戻ります。設定ファイルに書いていなければ、再起動も必要ありません。

3-4. 順序が結果を変える

# 自作 ls を優先したい
$ export PATH="$HOME/bin:$PATH"

# 既存の ls を優先したい(自作を後回し)
$ export PATH="$PATH:$HOME/bin"

役立つコツ: PATH を編集して動きが変わったときは、which コマンド名 を実行します。実際にどのファイルが呼ばれているかがわかり、原因に最短でたどり着けます。

3-5. リナの失敗:PATH を上書きしてしまう

リナ: export PATH="$HOME/bin" と打ったら、lscat も動かなくなりました。パソコンが壊れたんでしょうか。
ライニー先輩: 壊れてないよ。PATH を上書きしたから、シェルが /usr/bin を探さなくなっただけなんだ。
リナ: えっ、コマンドが消えたわけではないんですか。
ライニー先輩: そう。コマンドのファイルはちゃんとある。探しに行く場所の指示が消えただけだよ。
リナ: 場所の指示だけの問題だったんですね。安心しました。
ライニー先輩: 直し方は簡単。新しいターミナルを開けば元に戻る。.bashrc に書いていなければ、それだけで解決だよ。

その場で直す方法

新しいターミナルを開かずに直したいときは、次のように打ちます。

$ export PATH="/usr/local/bin:/usr/bin:/bin:$PATH"

これで最低限のコマンドが動くようになります。そのうえで、あらためて正しい書き方に直してください。

4. 永続化する:次のログインでも残す

結論: export は今のシェル限定。次回も残すには ~/.bashrc に書く。そして source で今すぐ反映する。

リナ: export で設定しました。それなのに、ターミナルを閉じたら消えてしまいました。
ライニー先輩: それが「永続化」の話だよ。export今のシェルだけ で有効なんだ。
ライニー先輩: 次に開いたときには忘れられている。残したいなら設定ファイルに書こう。

先に、壊れたときの戻し方

ここからは設定ファイルを編集します。書き方を間違えると、ターミナルを開くたびにエラーが出ることがあります。

編集の前にコピーを取ってください。

$ cp ~/.bashrc ~/.bashrc.bak

おかしくなったら、コピーから戻せます。

$ cp ~/.bashrc.bak ~/.bashrc
$ source ~/.bashrc

ターミナルが開いてすぐ閉じてしまう場合は、設定ファイルを読まずに起動できます。別のターミナルから bash --norc --noprofile と打てば、上の cp で元に戻せます。

4-1. どのファイルに書く?

ファイル いつ読まれる 主な用途
~/.bashrc bashの対話シェル起動時(毎回) 個人の環境変数・エイリアス
~/.profile / ~/.bash_profile ログイン時に1回 環境変数(SSH ログイン等)
/etc/environment システム全体・全ユーザー システム共通(rootすべての操作が許可された特別な管理者ユーザー。権限要)

迷ったら ~/.bashrc に書いてください。 GUI のターミナルや WSL では、このファイルが最も確実に読まれます。

4-2. .bashrc に書く例

末尾に追記する:

# 自作スクリプト置き場
export PATH="$HOME/bin:$PATH"

# 言語設定
export LANG=ja_JP.UTF-8

# エディタの指定
export EDITOR=vim

4-3. 編集後すぐ反映させる:source

$ source ~/.bashrc

または:

$ . ~/.bashrc

source を忘れて「PATH が反映されない」と悩む人は多いです。

設定ファイルを編集したら、必ず source を実行してください。 再ログインでも同じ効果があります。

リナ: source は何をしているのでしょうか。
ライニー先輩: 「このファイルを今のシェルで読み直す」という命令だよ。
ライニー先輩: ふつうにスクリプトを実行すると、別のプロセスで動く。だから export しても、その結果は親のシェルに戻ってこないんだ。
ライニー先輩: source なら今のシェルの中で実行される。だから設定がそのまま反映されるよ。

5. つまずきポイント集

結論: $ の付け忘れ・= 前後のスペース・PATH の上書き・クォートの違い。この 4 つが典型的な事故。

ライニー先輩: ここまでで基礎は身についたね。最後に 初心者がよくハマるポイント をまとめて潰しておこう。

5-1. $ を付け忘れる / 付けすぎる

# NG: ただの文字列「HOME」が表示される
$ echo HOME

# OK: 中身が展開される
$ echo $HOME

5-2. = の前後にスペース

# NG: コマンドとして解釈されてエラー
$ MY_VAR = hello

# OK
$ MY_VAR=hello

5-3. PATH の上書き事故

# 大事故!既存PATHが消える
$ export PATH="$HOME/bin"

# 正しい
$ export PATH="$HOME/bin:$PATH"

誤って上書きしてしまったときは、新しいターミナルを開いてください。 それだけで元の PATH に戻ります。あわてて .bashrc を編集する必要はありません。

5-4. ダブルクォートとシングルクォートの違い

$ NAME=lina

# ダブルクォート:$NAME が展開される
$ echo "Hello $NAME"
Hello lina
# シングルクォート:そのまま表示される
$ echo 'Hello $NAME'
Hello $NAME

鉄則: 変数を展開したいときは ダブルクォート "..." を使います。文字をそのまま出したいときは シングルクォート '...' を使います。

5-5. export したのにスクリプトで使えない

シェルスクリプトを ./script.sh の形で実行した場合、親シェルで export した変数は引き継がれます。

ただし新しいターミナルを開くと、シェルは .bashrc を読み直します。そのため .bashrc に書いていない変数は消えています。

スクリプトに渡したい変数は、.bashrc などに書いて永続化しておくのが確実です。

6. ミニ課題で手を動かそう

結論: 変数の表示・PATH への ~/bin 追加・自作コマンドの実行。3 問で設定から永続化までを体験する。

ライニー先輩: 知識だけでは身につかないよ。3 問だけ手を動かしてみよう。

課題 1: 自分の名前を変数に入れて、「Hello, 名前」の形で表示しよう。

ヒント 1(方向づけ)を見る

まず名前を箱に入れます。次にその箱の中身を、文の一部として画面に出します。文全体はクォート文字列を引用符(' や ")で囲むこと。スペースなどを含む値をひとまとまりとして扱える。で囲みます。

ヒント 2(コマンド名)を見る

代入は 変数名=値 の形です。表示は echo です。中身を展開したいので、囲むのはダブルクォート "..." です。

答えを見る
$ MY_NAME=lina
$ echo "Hello, $MY_NAME!"
Hello, lina!

MY_NAME の部分は、あなたの名前に置きかえてかまいません。= の前後にスペースを入れないでください。

課題 2: ~/bin というディレクトリを作り、次に開くターミナルでも PATH に含まれるようにしよう。

ヒント 1(方向づけ)を見る

ディレクトリを作ります。そのあと、設定ファイルの末尾に PATH を足す 1 行を書き加えます。最後にその設定ファイルを読み直します。

ヒント 2(コマンド名)を見る

作るのは mkdir -p です。書き足すのは echo>> です。読み直すのは source です。ファイルは ~/.bashrc です。

答えを見る
$ mkdir -p ~/bin
$ echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ echo $PATH
/home/lina/bin:/usr/local/bin:/usr/bin:/bin

先頭のほうに /home/あなたの名前/bin が入っていれば成功です。

ここでシングルクォートを使う理由があります。.bashrc に書く時点では展開させず、読み込むときに展開させたいからです。

課題 3: ~/bin に自作コマンドを置いて、どこからでも呼び出せるようにしよう。

ヒント 1(方向づけ)を見る

3 段階です。ファイルを作り、実行できる印を付け、名前だけで呼び出します。

ヒント 2(コマンド名)を見る

ファイル作成は cat > ファイル名 です。中身を打ち終えたら Ctrl+D で確定します。実行できる印を付けるのは chmod +x です。あとはファイル名を打つだけです。

答えを見る
$ cat > ~/bin/hello
#!/bin/bash
echo "Hello from my own script!"

2 行を打ったら Ctrl+D を押します。これで保存されます。

1 行目の #!/bin/bash は「このファイルは bash で実行する」という決まり文句です。シェバンと呼びます。

$ chmod +x ~/bin/hello
$ hello
Hello from my own script!

command not found が出る場合は、課題 2 の source ~/.bashrc を実行したか確認してください。

作ったファイルを消したいときは rm ~/bin/hello を実行します。rm で消したファイルはゴミ箱に入らず、その場で完全に消えます。消す前に ls ~/bin で中身を確かめてください。

リナ: できました。自分で作ったコマンドがどこからでも呼べるのは、うれしいです。
ライニー先輩: それが PATH の力だよ。これで command not found も怖くないね。

7. 振り返り

リナ: 整理します。$ は中身を呼び出すスイッチ。export を付けると子プロセスにも届く。
ライニー先輩: そのとおり。そして .bashrc に書けば、次に開いたターミナルでも残るね。
リナ: PATH は探しに行く場所の並び。command not found が出たら、まず echo $PATHwhich で確かめます。
ライニー先輩: 完璧だね。PATH を書きかえるときは、末尾の :$PATH を忘れないこと。それだけ覚えておけば大丈夫だよ。

8. 今日のまとめ

コピペ用:環境変数チートシート

# 見る
echo $HOME                # 1つだけ
env                       # 全部
env | grep PATH           # 絞り込み
which コマンド名          # コマンドの場所

# 設定する
MY_VAR=値                 # シェル変数(このシェル内のみ)
export MY_VAR=値          # 環境変数(子プロセスにも継承)
unset MY_VAR              # 削除

# PATH 追加(事故防止)
export PATH="$HOME/bin:$PATH"   # 必ず :$PATH を末尾に

# 永続化
vim ~/.bashrc             # 末尾に export を追記
source ~/.bashrc          # 即反映

やってはいけないこと

  • export PATH="$HOME/bin" で既存 PATH を吹っ飛ばす
  • MY_VAR = 値 のように = 前後にスペースを入れる
  • '$HOME' のシングルクォートで括って展開されないと悩む
  • .bashrc を編集したのに source を忘れて「反映されない」と悩む

今日の 3 行まとめ

  1. $VAR は変数の中身を呼び出す書き方。echo $HOMEenv で今の状態を読める
  2. export を付けた変数だけが、子プロセスに引き継がれる
  3. PATH を追加するときは、末尾に :$PATH を必ず付ける

次に読む