Linux: 環境変数とPATH — 開発環境の設定

環境変数はオペレーティングシステムが設定を保存するキーと値のペアです。シェルがコマンドを探す場所(PATH)、使用する言語(LANG)、使用するエディタ(EDITOR)などを決定します。

📋 前提条件:まず以下を完了していること

1. このレッスンで学ぶこと


2. 「command not found」ストーリー

(1) 悩み:インストールしたのに見つからない

小明はpip install --userでPythonツールhttpieをインストールしましたが、httpと入力すると:

BASH
http example.com
# Command 'http' not found

小明は混乱しました:「インストールしたのに、なぜシステムが見つけられないの?」

(2) PATH — シェルにプログラムの在り処を教える

ボブが説明しました。「プログラムはインストールされているけど、シェルはどこを探せばいいか知らない。PATH環境変数がシェルの『宝の地図』なんだ。」

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

# ~/.local/bin is not in PATH, so the Shell can't find http
ls ~/.local/bin/http*
# /home/charlie/.local/bin/http

# Add ~/.local/bin to PATH
export PATH="$PATH:$HOME/.local/bin"
http example.com    # Now it works

(3) 得られるもの:仕組みを理解すればすべて解決

小明は.bashrcexport PATH="$PATH:~/bin"を書けば永続化できることを学びました。今後新しいツールをインストールする際、インストール先ディレクトリがPATHにあるか確認すればいいと分かりました。


3. 知識ポイント

(1) 環境変数とは

環境変数はオペレーティングシステムに保存されるキーと値のペアで、すべての子プロセスに継承されます。

TEXT
# View all environment variables
printenv

# View individual variables
echo $HOME
echo $USER
echo $SHELL
echo $LANG
echo $PWD

よく使う環境変数:

変数 意味 典型的な値
HOME 現在のユーザーのホームディレクトリ /home/alice
USER 現在のユーザー名 alice
SHELL 現在のシェルパス /bin/bash
PATH コマンド検索パス /usr/bin:/bin:/usr/local/bin
LANG 言語とエンコーディング en_US.UTF-8
PWD 現在の作業ディレクトリ /home/alice/projects
OLDPWD 前の作業ディレクトリ /etc
EDITOR デフォルトエディタ vim

(2) PATH — コマンド検索パス

lsと入力すると、シェルはPATHにリストされた各ディレクトリを順番に検索し、lsプログラムを探します。見つかれば実行、見つからなければcommand not foundと報告します。

💡 ヒント:PATHは「順次検索」で動作します — シェルはPATHディレクトリを左から右に検索し、最初に一致した時点で停止します。PATHの前にあるディレクトリほど優先度が高いです。新しくインストールしたプログラムが動かない場合、古いバージョンが前方のPATHディレクトリにある可能性があります。

BASH
# View current PATH
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Find which directory a command is in
which ls
# /usr/bin/ls

# View all possible locations for a command (including aliases and functions)
type ls
# ls is aliased to `ls --color=auto'

(3) 環境変数の設定と削除

BASH
# Temporary setting (only effective in current Shell)
MY_VAR="hello"

# Export as environment variable (child processes can access it)
export MY_VAR="hello"

# Set and export in one command
export MY_VAR="hello"

# Unset an environment variable
unset MY_VAR

# Temporarily set for a single command (without polluting current environment)
LANG=ja_JP.UTF-8 date

(4) シェル設定ファイルの読み込み順序

読み込み順序を理解することは重要 — ~/.bashrcの変更が反映されない理由が分かります:

BASH

Login Shell (SSH login, tty login):
    /etc/profile
    ~/.bash_profile   (if it exists, the following two are skipped)
    ~/.bash_login
    ~/.profile

Non-login Shell (opening a new terminal):
    /etc/bash.bashrc
    ~/.bashrc

ℹ️ 注意.bashrc.profileは異なるタイミングで読み込まれます — SSHログインは.profileを、新しいターミナルの起動は.bashrcを読み込みます。ベストプラクティスは.profilesource ~/.bashrcを追加し、すべての設定を.bashrcに書くこと — これによりログイン方法に関わらず設定が有効になります。

ベストプラクティス: .bash_profileに以下を追加:

BASH
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi

すべてのカスタム設定は.bashrcに書きます。

(5) ▶ サンプル:環境変数の確認と設定

BASH
# View environment variables
echo "My home directory is: $HOME"
echo "Current user: $USER"
echo "My Shell: $SHELL"

# Set a temporary variable
export GREETING="Hello from Linux"
echo $GREETING

# Open a new terminal window and check if $GREETING is still there
# Answer: No — temporary variables only exist in the current Shell

出力:

TEXT
My home directory is: /home/alice
Current user: alice
My Shell: /bin/bash
Hello from Linux

(6) ▶ サンプル:PATHを理解する

BASH
# View current PATH
echo $PATH | tr ':' '\n'    # Display one path per line

# Find which directory ls is loaded from
which ls
# /usr/bin/ls

# What happens if PATH is wrong?
PATH=""      # Clear PATH (dangerous!)
ls
# bash: ls: No such file or directory

# Restore PATH
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

出力:

TEXT
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/bin/ls

(7) ▶ サンプル:~/scriptsをPATHに追加(永続的)

BASH
# Create your own scripts directory
mkdir -p ~/scripts

# Add ~/scripts to PATH (write to .bashrc)
echo 'export PATH="$PATH:$HOME/scripts"' >> ~/.bashrc

> 💡 ヒント:環境変数を永続化するには、`export`コマンドを`~/.bashrc`(または`~/.profile`)に書く必要があります。修正後は`source ~/.bashrc`で即座に反映。そうでなければ新しい設定は新しく開いたターミナルでのみ読み込まれます。

# Reload
source ~/.bashrc

# Verify
echo $PATH | tr ':' '\n' | grep scripts
# /home/alice/scripts

出力:

TEXT
/home/alice/scripts

(8) ▶ サンプル:よく使う開発環境変数の設定

BASH
# Add the following to ~/.bashrc

# Default editor
export EDITOR=vim

# Locale
export LANG=en_US.UTF-8

# Python development
export PYTHONSTARTUP=~/.pythonrc    # Python interactive startup script
export PIP_REQUIRE_VIRTUALENV=true  # pip requires virtual environment

# Node.js development
export NODE_ENV=development
export npm_config_prefix=~/.npm-global

# Go development
export GOPATH=$HOME/go
export PATH="$PATH:$GOPATH/bin"

# Your own scripts
export PATH="$PATH:$HOME/scripts"
export PATH="$PATH:$HOME/.local/bin"

出力:

TEXT
EDITOR=vim
LANG=en_US.UTF-8
PYTHONSTARTUP=/home/alice/.pythonrc
PIP_REQUIRE_VIRTUALENV=true
NODE_ENV=development
GOPATH=/home/alice/go

(9) ▶ サンプル:コマンドが見つかるか確認

BASH
# Use which to find the command path
which python3
# /usr/bin/python3

# Use type to check command type (alias/function/builtin/external)
type ls
# ls is an alias for `ls --color=auto'
type cd
# cd is a shell builtin
type node
# node is /usr/bin/node

# Use command -v (most reliable method)
command -v python3
# /usr/bin/python3

出力:

TEXT
/usr/bin/python3
ls is an alias for `ls --color=auto'
cd is a shell builtin
node is /usr/bin/node
/usr/bin/python3

(10) ▶ 総合例:「command not found」問題のデバッグ

BASH
#!/bin/bash
# debug-path.sh - Debug command-not-found issues

CMD="${1:-http}"

echo "=== 1. What is the command ==="
type "$CMD" 2>/dev/null || echo "type: $CMD not found"

echo ""
echo "=== 2. Which PATH directories contain this command ==="
IFS=':' read -ra PATHS <<< "$PATH"
for dir in "${PATHS[@]}"; do
    if [ -f "$dir/$CMD" ]; then
        echo "Found: $dir/$CMD"
    fi
done

echo ""
echo "=== 3. Global search with find ==="
find /usr /opt $HOME -name "$CMD" -type f 2>/dev/null | head -5

echo ""
echo "=== 4. If found but not in PATH ==="
echo "Run: export PATH=\"\$PATH:/found/directory\""

❓ よくある質問

Q: PATHの順序は重要ですか? A: 非常に重要です!シェルはPATHディレクトリを順番に検索し、最初に一致した時点で停止します。/usr/local/binが先にあれば、/usr/binより優先されます。新しくインストールしたプログラムが古いバージョンで動く場合は、PATHの順序を確認してください。

Q: 環境変数は再起動後に消えますか? A: exportで設定した一時変数は再起動後に失われます。永続化するにはexportコマンドをシェル設定ファイル(~/.bashrc~/.bash_profile)に書く必要があります。

Q: .bashrc.bash_profileはどちらが先に実行されますか? A: ログインシェル:/etc/profile~/.bash_profile~/.bash_login~/.profile(前のファイルが存在しない場合)。非ログインシェル:/etc/bash.bashrc~/.bashrc

Q: 全ユーザー向けのグローバル環境変数の設定方法は? A: /etc/environment(単純なキーと値のペア、スクリプト不可)または/etc/profile.d/custom.sh(シェル構文対応、root権限が必要)に書きます。

Q: printenvsetの違いは? A: printenvは環境変数(エクスポート済み)のみ表示。setはシェルローカル変数や関数を含むすべての変数を表示。完全な環境確認にはprintenv、スクリプトのデバッグにはsetを使います。


📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐):現在のPATHを確認(tr ':' '\n'で1行ずつ表示)、which python3type cdでコマンドの種類を理解する
  2. 中級(難易度 ⭐⭐)~/scriptsディレクトリを作成し、簡単なhello.shスクリプトを書き、PATHに追加して直接実行。.bashrcEDITOR=vim(またはnano)を設定しsourceで確認する
  3. 上級(難易度 ⭐⭐⭐):コマンド名を引数に取るdebug-path.shスクリプトを作成 — PATHにあるか自動チェック、どのディレクトリに含まれるか確認、PATHにない場合は修正を提案する
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%