【Linux】環境変数とPATHの通し方|export・command not foundの解決・.bashrc

【Linux】環境変数とPATHの通し方|export・command not foundの解決・.bashrc Linux

「インストールしたはずのコマンドがcommand not foundになる」「PATHを通すってどういう意味?」——Linuxを使い始めると必ずぶつかるのが、環境変数PATHです。環境変数は「シェルやプログラムが参照する設定値」で、その代表格のPATHは「コマンドを探しに行くディレクトリの一覧」です。

つまずきやすいのは、exportを付けない変数は、そこから起動したプログラム(子プロセス)に引き継がれないことと、ターミナルで設定した変数は閉じると消える(永続化には.bashrcが必要)ことです。この記事では、実機のLinux(WSLのDebian)でcommand not foundを実際に再現し、PATHを通して解決するまでを実演しながら整理します。

先に結論

  • 環境変数はexport 名前=値で設定します。exportが無いと子プロセスに渡りません
  • PATHはコロン区切りのディレクトリ一覧。コマンドはここから探されます。
  • 「PATHを通す」=export PATH="$PATH:追加したいディレクトリ"です。
  • ターミナルを閉じると消えるため、恒久設定は~/.bashrcに書きます。
  • 確認はecho $PATHenvwhich コマンド名
  • VAR=値 コマンドと前置きすると、そのコマンド1回だけ有効にできます。

コマンドの実行に必要な権限はchmod(+xで実行権限)、設定ファイルの編集後の確認はgrep、ほかの基本はよく使うLinuxコマンドまとめもあわせて参考になります。

スポンサーリンク

環境変数とは・exportの意味

環境変数は名前=値の形で設定し、$名前で参照します。重要なのはexportの有無です。exportを付けて初めて、そのシェルから起動するプログラムに引き継がれます。

export の有無で挙動が変わる
# ただの代入(シェル変数): このシェルの中だけ
MY_VAR="hello"
echo $MY_VAR          # hello(自分では見える)
bash -c 'echo $MY_VAR' # (空)← 子プロセスには渡らない!

# export すると環境変数になり、子プロセスにも渡る
export MY_VAR
bash -c 'echo $MY_VAR' # hello

# 定義と export を同時に
export API_KEY="abc123" 
exportしないと子プロセスに渡らない(実証)

実機で確認したところ、MY_VAR="hello"と代入しただけの状態では、そこから起動した子プロセス(bash -c)で$MY_VARでした。export MY_VARを実行したあとは、子プロセスでもhelloが見えるようになりました。exportの無い変数は「シェル変数」で、そのシェルの中だけの存在です。プログラム(Node.js・Python・各種ツール)から参照させたい設定値は、必ずexportを付けてください。「スクリプトの中では見えるのに、そこから呼んだプログラムには渡っていない」というトラブルは、ほぼこのexport忘れが原因です。設定済みの環境変数の一覧はenvコマンドで確認でき、exportした変数だけがそこに載ります。

PATHの仕組み

PATHは環境変数の中でも特別に重要で、「コマンド名だけで実行されたとき、実体をどのディレクトリから探すか」の一覧です。コロン(:)区切りで複数のディレクトリが並んでいます。

PATH を確認する
# PATH の中身を見る(コロン区切りのディレクトリ一覧)
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:...

# コマンドの実体がどこにあるかを調べる
which ls        # /usr/bin/ls など
which python3   # /usr/bin/python3

# ls と打つと、PATH のディレクトリを左から順に探して
# 最初に見つかった実体が実行される

実機でも、echo $PATH/usr/local/sbin:/usr/local/bin:...というコロン区切りの一覧が確認できました。lspython3とコマンド名だけ打てるのは、シェルがPATHのディレクトリを左から順に探して実体を見つけてくれるからです。which コマンド名を使うと、実際にどこの実体が使われるかが分かります。逆に言えば、PATHに含まれないディレクトリにあるプログラムは、名前だけでは実行できません。これが次のcommand not foundの正体です。

command not found をPATHで解決する(実演)

「インストールしたのにcommand not found」の典型パターンを、実際に再現して解決してみます。実体はあるのにPATHに載っていないのが原因です。

再現から解決まで
# 自作コマンドを PATH 外のディレクトリに置く
mkdir -p ~/mybin
echo '#!/bin/bash
echo "hello from mybin"' > ~/mybin/hello-cmd
chmod +x ~/mybin/hello-cmd

# 名前だけで実行 → 見つからない
hello-cmd
# bash: hello-cmd: command not found

# PATH にディレクトリを追加(既存の PATH の後ろに足す)
export PATH="$PATH:~/mybin"

# もう一度実行 → 動く!
hello-cmd
# hello from mybin

実機でも、PATH外に置いた自作コマンドはcommand not foundになり、export PATH="$PATH:ディレクトリ"でPATHに追加した直後から名前だけで実行できるようになりました(whichでも追加したディレクトリの実体が表示されました)。これが「PATHを通す」の意味のすべてです。ポイントは"$PATH:追加分"のように既存のPATHを含めて書くことです。export PATH="~/mybin"のように上書きしてしまうと、lsすら見つからなくなります。なお、実体には実行権限(chmod +x)も必要です。

永続化する(~/.bashrc)

注意したいのは、ターミナルでexportした変数は、そのターミナルを閉じると消えることです。次回以降も有効にするには、シェルの設定ファイル~/.bashrcに書いておきます。

~/.bashrc で永続化
# ~/.bashrc の末尾に追記する
echo 'export PATH="$PATH:$HOME/mybin"' >> ~/.bashrc

# 今開いているターミナルに反映するには source
source ~/.bashrc

# 以後、新しいターミナルでも自動で PATH が通っている
exportは揮発性・恒久設定は.bashrcへ

ターミナルでのexportは、そのシェルのセッション限りです。閉じたり新しいタブを開いたりすると設定は消えています。「昨日通したはずのPATHがまた通っていない」というのは、これが原因です。恒久化するには、~/.bashrc(bashの場合。zshなら~/.zshrc)にexport行を書いておきます.bashrcはシェルの起動時に毎回読み込まれるため、以後は自動で設定されます。書いた直後の今のターミナルに反映したいときはsource ~/.bashrcで読み込み直します。追記には上書きの>ではなく追記の>>を使うことにも注意してください(>だと.bashrcの中身が全部消えます)。

一時的な指定(前置き)と確認コマンド

環境変数をそのコマンド1回だけ有効にしたいときは、コマンドの前にVAR=値を置きます。また、設定の確認にはenvechowhichを使い分けます。

一時指定と確認
# コマンドの前に置くと、その実行時だけ有効
NODE_ENV=production node app.js

# 実行後、シェルには残らない
echo $NODE_ENV    # (空)

# 確認コマンドの使い分け
env                  # export 済みの環境変数を一覧
echo $PATH           # 特定の変数の値を表示
which コマンド名      # コマンドの実体の場所

実機でも、TMP_ONLY=abc bash -c 'echo $TMP_ONLY'はそのコマンド内でだけabcが見え、実行後のシェルでは空のままでした。この前置き方式は「1回だけ環境を変えて実行したい」とき(本番モードでの起動テストなど)に便利で、シェルを汚しません。env | grep 名前とすれば、目的の変数が設定されているかをすぐ確認できます。

主なコマンド・書き方一覧

環境変数とPATHの操作をまとめます。

書き方 働き
export VAR=値 環境変数を設定(子プロセスに渡る)
VAR=値(exportなし) シェル変数(子プロセスに渡らない)
echo $VAR 値の確認
env 環境変数の一覧
export PATH="$PATH:追加" PATHを通す
which コマンド 実体の場所を確認
~/.bashrc に追記 + source 永続化と反映
VAR=値 コマンド 1回だけの一時指定

よくある失敗

exportを忘れてプログラムに渡らない

代入だけではシェル変数です。プログラムから参照させるにはexportを付けます。

PATHを上書きしてlsまで動かなくなる

export PATH="$PATH:追加分"のように、必ず既存の$PATHを含めます。

ターミナルを閉じて設定が消える

exportはセッション限りです。恒久設定は~/.bashrcに書きます。

.bashrcに書いたのに反映されない

既存のターミナルには自動反映されません。source ~/.bashrcを実行します。

>で.bashrcを上書きしてしまう

追記は>>です。>を使うと設定ファイルの中身が消えます。

よくある質問

Q「PATHを通す」とはどういう意味ですか?
Aコマンドの実体があるディレクトリを、環境変数PATHの一覧に追加することです。export PATH="$PATH:追加したいディレクトリ"と書きます。PATHに載っていれば、コマンド名だけで実行できるようになります。実機でも、command not foundだった自作コマンドが、PATH追加直後に実行できるようになることを確認しています。
Qexportは何のために付けるのですか?
Aそのシェルから起動するプログラム(子プロセス)に変数を引き継ぐためです。exportの無い代入はシェル変数で、自分のシェル内でしか見えません。実機でも、export前は子プロセスで空・export後は値が見えることを確認しています。プログラムに渡す設定値には必ずexportを付けてください。
Q設定した環境変数が次の日には消えています。
Aターミナルでのexportは、そのセッション限りだからです。恒久的に設定するには、~/.bashrc(zshなら~/.zshrc)にexport行を追記してください。シェルの起動時に毎回読み込まれるため、以後は自動で設定されます。今のターミナルに反映するにはsource ~/.bashrcです。
Qインストールしたコマンドがcommand not foundになります。
A実体がPATHに含まれないディレクトリにあることが原因です。まずインストール先を確認し(ドキュメントやfindで探す)、export PATH="$PATH:そのディレクトリ"でPATHに追加します。恒久化するなら~/.bashrcに書いてください。実体に実行権限(chmod +x)があることも確認しましょう。
Q環境変数を1回だけ変えて実行するには?
Aコマンドの前にVAR=値を置きます。NODE_ENV=production node app.jsのように書くと、その実行時だけ有効で、シェルには残りません。設定を汚さずに動作を試したいときに便利です。

まとめ

  • 環境変数はexport VAR=値exportが無いと子プロセスに渡りません
  • PATHはコマンドを探すディレクトリの一覧(コロン区切り)。
  • 「PATHを通す」=export PATH="$PATH:追加分"(既存PATHを必ず含める)。
  • 永続化は~/.bashrcに追記>>で)+sourceで反映。
  • 確認はenvecho $VARwhich、一時指定は前置きVAR=値 コマンド

環境変数とPATHは、Linuxの「コマンドが動く仕組み」の根っこです。「exportしないと渡らない」「PATHは既存を含めて追記」「恒久化は.bashrc」の3点を押さえれば、command not foundにも設定が消える問題にも、自信を持って対処できます。