環境変数とシェルの仕組み
シェルが「コマンドをどこで探すか」を決める PATH の読み方から、export で環境変数を作り、~/.bashrc に書いて永続化し、source で即反映するまでの 4 ステップを手を動かして身につけます。
| 所要時間 | 約 30 分 |
|---|---|
| 章タイプ | standard |
| 前提知識 | Chapter 1-5(SSH / パス / ファイル操作 / grep / vim 編集) |
| 使用機材 | 踏み台 workstation01 + 演習用サーバ learner01 |
| 関連章 | 前: Chapter 5「ファイルを書き換える(vim 入門)」/ 後: Chapter 7「ユーザとパーミッション」 |
「コマンドが動く裏側」を覗く
ここまでの章で、あなたはたくさんの コマンド を打ってきました。ls、cd、grep、vim ── これらはどこから来て、なぜシェルが理解できるのでしょうか?
ls と打って Enter を押した瞬間、シェルは決まった手順で動いています。「探す場所」のリストを持っているのが PATH という変数で、これは 環境変数 と呼ばれる仕組みのひとつです。
・「
command not found と言われる理由」が分かる・
~/.bashrc に何を書けば設定が永続化されるか分かる・Part 3 以降で SSH や nginx の設定をする前提が整う
この章を終えるとできること
環境変数のライフサイクル 4 ステップ を手に覚えます。
現状を確認
その場限り設定
追記して永続化
シェルに即反映
この 4 ステップが体になじむと、PATH を通したり、エイリアスを永続化したり、開発環境を整えるのが自由になります。
概念説明
1. シェルとは何か
workstation01 や learner01 に SSH ログインした瞬間、シェル というプログラムが起動します。Linux で最も一般的なのは bash(Bourne Again SHell)です。
echo $SHELL # → /bin/bash
2. 環境変数とは ── シェルが持っている「メモ」
環境変数 は、シェルが持っている 名前付きのメモ です。変数名=値 という形で覚えています。
| 変数名 | 何を覚えているか | 例 |
|---|---|---|
PATH | コマンドを探す場所のリスト | /usr/local/bin:/usr/bin:/bin |
HOME | あなたのホームディレクトリ | /home/student |
USER | あなたのユーザー名 | student |
SHELL | 使っているシェルの場所 | /bin/bash |
LANG | 言語・文字コード設定 | en_US.UTF-8 |
PS1 | プロンプトの表示形式 | \u@\h:\w\$ |
環境変数を参照するときは $ を頭に付けます。全部まとめて見たいときは env を使います。
echo $HOME # → /home/student echo $USER # → student env | grep PATH # PATH を含むものだけ(Ch4 のパイプを応用)
3. PATH ── コマンドを探す場所
ls と打ったとき、シェルは PATH に並んでいるディレクトリを 左から順に 探しに行きます。各ディレクトリを : で区切ったリストです。最初に見つかったものが使われます。
which ls # → /usr/bin/ls (ls の実体はここ) which vim # → /usr/bin/vim which grep # → /usr/bin/grep
command not found の正体
PATH のどこにも実行ファイルが見つからない」 という意味です。原因は 3 つに切り分けられます。| 原因 | 確認方法 | 対処 |
|---|---|---|
| そもそも入っていない | パッケージ管理で探す | apt install ... でインストール |
| 入っているが PATH 外 | find / -name xxx 2>/dev/null( 2>/dev/null = エラーメッセージを捨てる書き方) | PATH に追加する |
| タイプミス | which 似た名前 | 正しいスペルで打ち直す |
4. 環境変数のライフサイクル
環境変数は どこに書くか で「どこまで生き残るか」が変わります。
| 設定方法 | 生きる範囲 |
|---|---|
export VAR=value を打つ | 今のシェルだけ(ターミナルを閉じると消える) |
~/.bashrc に書く | 今後そのユーザーで起動するシェル全部 |
/etc/environment に書く | 全ユーザー / システム全体(管理者用) |
VAR=value だけだとシェル変数(その場限り)、export VAR=value だと環境変数(子プロセスにも渡る)になります。子プロセスとは、今のシェルから呼び出されたコマンドやスクリプトのこと(親から渡された値を子も知っている状態)。コマンドや別シェルから参照したいなら export を付ける、と覚えれば十分です。
5. .bashrc と .bash_profile の違い
ここがハマりどころです。bash は起動の仕方によって 読むファイルが違います。
| ファイル | いつ読まれるか |
|---|---|
~/.bash_profile | ログインシェル(SSH で入った瞬間など) |
~/.bashrc | インタラクティブシェル(新しいターミナル / bash 起動など) |
~/.profile | ~/.bash_profile が無いときのフォールバック |
~/.bashrc に書く。多くの Linux ディストリビューションでは
~/.bash_profile の中で ~/.bashrc を source する構成になっているので、~/.bashrc に書けば両方のケースで反映されます。6. source ── 設定を「今すぐ」反映する
~/.bashrc を編集しても、今動いているシェルには反映されません(次にログインしたとき初めて読まれる)。
source ~/.bashrc # 今のシェルに即座に反映 . ~/.bashrc # 同じ(ドット 1 個でも source と同じ意味)
または、いったん exit して再 SSH すれば、新しいシェルが起動するときに .bashrc が読まれます。
試してみよう:自作スクリプトをコマンドのように使う
シナリオ: 「自分専用のスクリプト hello を作って、どこからでも hello と打って実行できるようにする」 ── 実際の現場でも、自作の運用スクリプトを ~/bin/ に置いて PATH を通す手順は頻出です。
触るのは ~/bin/(新規作成)と ~/.bashrc(追記)だけ。~/.bashrc の元の中身は変更しません。
もし ~/.bashrc がおかしくなったら、追記した行を vim で削除すれば元に戻ります。
まず learner01 に入る
ssh student@learner01
見る ── 現在の PATH を確認
: で区切られたディレクトリのリストが出ます。
echo $PATH # /usr/local/bin:/usr/bin:/bin:... echo $HOME # /home/student echo $USER # student env | grep -i lang # 言語設定
自作スクリプトを作る場所を用意
mkdir -p ~/bin # 自作スクリプトを置く慣例の場所
vim で簡単なスクリプトを書く
まず、~/bin/hello が すでにあるか を確かめます。
cat ~/bin/hello # → 中身が表示された:すでにファイルがある(下の ★ を先に読む) # → cat: /home/student/bin/hello: そのようなファイルやディレクトリはありません:まだ無い(そのまま次へ)
cat で中身が表示された人へ —— それで正常です: この演習環境には ~/bin/hello が最初から置いてあります。そのまま i で入力すると 既存の行に同じ内容が足されて重複します。入力を始める前に、中身を全部消してから書き直してください(全置換)。Chapter 5 で練習した操作だけで消せます —— vim ~/bin/hello で開いたら gg(先頭行へ)→ dd を 画面から行がなくなるまで 繰り返す → 空になったら i で下の 2 行を入力。消しすぎたときは u で戻せます。vim で ~/bin/hello を開く →(既存の行があれば gg → dd で全部消す)→ i でインサート → 以下を入力 → Esc → :wq。
#!/bin/bash echo "こんにちは、$USER さん! (from learner01)"
# を付けてくるとき(ここで必ず起きます): 1 行目の #!/bin/bash を書いて Enter を押すと、2 行目の先頭にも # が自動で入ります(vim が「コメントの続き」だと判断するためです)。そのまま echo ... を書くと #echo ... になり、行数は 2 行のままなのにスクリプトは何も表示しなくなります。付いてしまったら Esc でノーマルモードに戻り、2 行目の先頭へ移動して x で # を 1 文字消します。Chapter 8 でも同じことが起きます。保存したら、中身が 上の 2 行と完全に同じか 確かめます。行数だけではなく、2 行目が echo で始まっているか(#echo になっていないか)を必ず見てください。
cat ~/bin/hello # → #!/bin/bash # → echo "こんにちは、$USER さん! (from learner01)"
見るべきは次の 2 点です。
- 2 行目が
#echoになっていないか —— なっていたら上の注記のとおり x で#を 1 文字消す。行数は 2 行のままなので、行数だけ見ていると見逃します - 3 行以上になっていないか —— なっていたら重複です。もう一度 vim で開き、
gg→ddで全部消してから 2 行を入力し直す
実行権限を付けます(Ch7「ユーザとパーミッション」で詳しく扱う chmod +x です)。
chmod +x ~/bin/hello
パスを指定して実行してみる
~/bin/hello # フルパスなら動く # → こんにちは、student さん! (from learner01)
#echo になっています(STEP 4 の vim 自動コメント)。スクリプト自体は正常に実行されており、中身が全部コメントなので何もしないだけです。cat ~/bin/hello で 2 行目を見て、# が付いていたら vim ~/bin/hello で開き、Esc → 2 行目の先頭へ移動 → x → :wq で修正してからこの STEP をやり直してください。ここを通さないと Chapter 7 の演習も成立しません。hello だけで実行 → command not found を体感
hello
# → bash: hello: command not found
command not found になったなら、PATH に ~/bin が含まれていないため、シェルが hello を見つけられなかったということです。which hello を打っても何も返ってきません。逆に、そのまま hello が動いた場合も正常です ── 理由は下の注記のとおりで、どちらの結果でもこの章の学びは同じです。
command not found にならず hello が動いた人へ: それで正常です。Ubuntu の ~/.profile には「~/bin が存在すれば、ログイン時に自動で PATH の先頭へ足す」処理が最初から入っています。この演習環境には ~/bin が用意してあるので、ログインした時点ですでに PATH に入っており、名前だけで呼べます(echo $PATH の先頭で確かめられます)。「PATH に入っていれば名前だけで呼べる / 入っていなければフルパスが要る」というこの章の結論を、先に体験できている状態です。次の STEP は、その仕組みを自分の手で作り直して確かめる工程なので、そのまま進めてください。作る ── PATH に一時的に ~/bin を追加
export PATH="$HOME/bin:$PATH" echo $PATH # 先頭に /home/student/bin が追加されたか確認(元から入っていた人は 2 つ並ぶ・害はない) hello # 今度は動く which hello # /home/student/bin/hello
動きました。ただしこれは 今のシェルだけ。exit して再ログインすると消えます。
保存する ── ~/.bashrc に追記して永続化
念のため、編集前に .bashrc.bak というバックアップを作っておきます。演習環境なので大きな事故にはなりませんが、現場では設定ファイルを触る前に戻せる状態を作るのが基本です(Chapter 3 の「変更前バックアップ」と同じ考え方です)。
cp ~/.bashrc ~/.bashrc.bak
続けて vim で ~/.bashrc を開き、末尾(G でジャンプ → o で新しい行)に以下を追加して :wq。
# を付けてくるとき: 1 行目のコメント # 自作スクリプト用 を書いて Enter を押すと、次の行の先頭にも # が自動で入ることがあります(vim が「コメントの続き」だと判断するためです)。そのまま export ... を書くと その行はコメント扱いになり、PATH は設定されません。付いてしまったら Esc でノーマルモードに戻り、その行の先頭へ移動して x で # を 1 文字消します。grep PATH ~/.bashrc で export の行頭に # が無いことを必ず確認してください。# 自作スクリプト用 export PATH="$HOME/bin:$PATH"
grep PATH ~/.bashrc で確認し、すでに同じ行があればそのまま次へ。同じ export PATH 行が 2 行あっても動作はしますが、無駄なので 1 行にしておきましょう。反映する ── source で今のシェルに反映
source ~/.bashrc # 今のシェルに即反映 which hello # /home/student/bin/hello hello # 動く
これで、次回以降ログインしても hello がどこからでも実行できます。
詰まったら
- 段階ヒント: 定番の詰まりポイントへの段階開示
- AI に相談: AI アシスタントに自由質問できる相談窓口
💡 軽く方向だけ
which コマンド名 で「どこから読まれているか」を確認、echo $PATH で「どこを探しているか」を確認。この 2 つを突き合わせると原因が見えます。
💡 具体的な手順
# 確認 echo $PATH # 探す場所のリスト which hello # シェルが見ている実体 # 一時追加 export PATH="$HOME/bin:$PATH" # 永続化 vim ~/.bashrc # 末尾に export PATH="$HOME/bin:$PATH" を追記 source ~/.bashrc # 即反映
$PATH の前後関係: PATH="$HOME/bin:$PATH" は「先頭に追加」で、自作スクリプトがシステム標準より優先されます(この章ではこちらを採用)。逆に PATH="$PATH:$HOME/bin" なら「末尾に追加」で、システム標準が優先。~ ではなく $HOME を使うと、どんな場面でも確実にホームディレクトリに展開されます。
✅ 答えを見る
mkdir -p ~/bin vim ~/bin/hello # 既存の hello がある場合は gg → dd を繰り返して全部消してから入力(全置換) # 2 行目に vim が自動で付ける # は x で消す(#echo のままだと無出力) # vim 内で: #!/bin/bash echo "こんにちは、$USER さん!" # 保存して終了 chmod +x ~/bin/hello # 一時的に PATH 追加 export PATH="$HOME/bin:$PATH" hello # 動作確認 # 永続化 vim ~/.bashrc # 末尾に export PATH="$HOME/bin:$PATH" を追記 source ~/.bashrc which hello # /home/student/bin/hello hello # 動く
ポイント: export で環境変数として設定、~/.bashrc で永続化、source で即反映。この 3 段階を意識すれば、設定の生存範囲が掴めます。
AI に相談
修了確認
学んだことが身についたか、2 問だけ確認してみましょう。
~/.bashrc と ~/.bash_profile は、それぞれ どんなタイミングで読まれる ファイルですか? また、「迷ったらどっちに書けばいい?」 という現場の合言葉に答えてください。mycmd: command not found というエラーが出ました。原因として考えられる 3 つのパターン を挙げ、それぞれの 確認コマンド を答えてください。次の章へ
次は Chapter 7「ユーザとパーミッション」 です。
ls -l を打つと出てくる -rw-r--r-- という謎の文字列、chmod 755 という呪文 ── これらは Linux の 権限システム です。Ch6 の演習で chmod +x を打ったのを覚えていますか? あれの仕組みを次に解剖します。