「command not found」の原因と対処法|パスと環境の考え方
コマンドを打った瞬間に command not found と出ると、つい「インストールに失敗したのか」と考えがちです。ですが実際には、コマンド本体がないよりも、シェルがその場所を探せていないことのほうがよくあります。
このページでは、PATH と環境変数の基本を押さえながら、Linux/macOS のターミナルと Windows の cmd / PowerShell で共通する見方を整理します。Python の仮想環境や自作スクリプトでもそのまま使える考え方です。
- 最初に見るべきは
PATH。コマンド名だけ打ったとき、シェルはPATHに並んだフォルダを順番に探します。 - インストール済みでも失敗することがあります。フォルダが
PATHに入っていない、別のシェル設定しか読まれていない、再起動前の古い環境が残っている、などが典型です。 - 確認は3段階で進めると早いです。
PATHを見る、コマンドの実体を探す、実行権限や仮想環境を確認する。この順で切り分けると迷いにくくなります。
ここがポイント:
command not foundは「そのコマンドが存在しない」という意味ではなく、「今のシェル設定では見つけられない」という意味で出ることが多いエラーです。
まず押さえたい前提
ここで扱う主な対象環境は次の通りです。
- Linux / macOS の
bashまたはzsh - Windows の
cmd.exeと PowerShell - Python 仮想環境
venvを使う場面
Bash の公式マニュアルでは、コマンド名にスラッシュがない場合、シェルは関数や組み込みコマンドを確認したあと、$PATH の各要素を順に検索します。見つからなければエラーになり、Bash では終了ステータス 127 が返ります。つまり、PATH は「コマンド検索の対象フォルダ一覧」です。
Windows でも考え方は同じです。Microsoft のドキュメントでも、PATH は実行ファイルを探すためのディレクトリ集合として説明されています。違うのは表現だけで、根本は同じです。
command not found の主な原因
見つからない理由は、だいたい次の5つに整理できます。
1. そもそもインストールされていない
もっとも単純なケースです。たとえば node や python を使うつもりでも、まだ本体が入っていなければ当然見つかりません。
確認の目安:
- Linux/macOS:
command -v コマンド名またはtype -a コマンド名 - Windows:
where コマンド名
何も返らないなら、まずインストール有無を疑います。
2. インストール先が PATH に入っていない
実務ではこれが非常に多いです。たとえば以下のような場面です。
- 自作 CLI を
~/tools/binに置いた npmのグローバルコマンドを使いたいpipで入れた実行スクリプトがユーザー領域に置かれた- Homebrew や独自インストーラで入れたが、設定ファイルに追記されていない
ファイル自体は存在していても、そのフォルダが PATH にないと、コマンド名だけでは実行できません。
3. 設定ファイルを編集したのに、今のシェルに反映されていない
~/.bashrc や ~/.zshrc を書き換えても、その設定を今開いているシェルがまだ読んでいないことがあります。
よくある例:
~/.zshrcを直したのに、ターミナルを再起動していない~/.bash_profileに追記したが、実際に使っているのはzsh- GUI から開いたターミナルと、VS Code 内蔵ターミナルで読み込む設定が違う
4. 実行ファイルではない、または実行権限がない
Linux/macOS では、ファイルがあっても実行権限がなければコマンドとして動きません。
例:
ls -l ./myscript
chmod +x ./myscript
また、PATH に入れるべきなのは通常「ファイルそのもの」ではなく「そのファイルが入っているディレクトリ」です。ここを逆にしてしまうと、見つからない原因になります。
5. 仮想環境やシェルごとの環境差を見落としている
Python の venv は典型例です。公式ドキュメントでも、仮想環境を有効化すると bin もしくは Scripts ディレクトリが PATH の先頭に追加されると説明されています。つまり、仮想環境を有効化している端末では見つかるのに、別の端末では見つからない、という差が起きます。
これは Python だけの話ではありません。Node.js のバージョンマネージャ、Java の SDK 管理ツール、社内ツールチェーンでも同じことが起きます。
まずやる確認手順
ここからは、実際に詰まりにくい順番で見ていきます。
1. PATH を表示する
Linux/macOS:
echo "$PATH"
Windows cmd:
echo %PATH%
PowerShell:
$env:Path
ここで見るポイントは、目的のコマンドが入っているフォルダが含まれているかです。
たとえば自作 CLI が /Users/name/tools/bin/mycmd にあるなら、PATH に必要なのは /Users/name/tools/bin です。/Users/name/tools/bin/mycmd ではありません。
2. コマンドの場所を引けるか確認する
Linux/macOS:
command -v python
command -v mycmd
type -a python
Windows:
where python
where mycmd
ここでパスが返れば、シェルは少なくとも見つけられています。返らないなら、PATH かインストール場所の問題です。
3. 実体があるか直接確認する
Linux/macOS:
ls -l /usr/local/bin/mycmd
Windows PowerShell:
Get-ChildItem "C:\path\to\tool\mycmd.exe"
コマンド名で呼べないときでも、絶対パスで実行できるなら、原因はかなり高い確率で PATH です。
典型パターン別の対処法
ケース1: コマンドはあるのに見つからない
この場合は、PATH にディレクトリを追加します。
Linux/macOS の例
zsh を使っているなら、たとえば ~/.zshrc に追記します。
export PATH="$HOME/tools/bin:$PATH"
反映:
source ~/.zshrc
bash なら ~/.bashrc や ~/.bash_profile を使うことがあります。どのファイルが読まれるかは起動方法で変わるので、使っているシェルを先に確認したほうが安全です。
echo "$SHELL"
Windows の例
Windows ではユーザー環境変数またはシステム環境変数の Path にフォルダを追加します。ドキュメントでも、子プロセスは親プロセスの環境変数を引き継ぐと説明されています。つまり、Path を変更したあと、既に開いているターミナルには反映されないことがあります。
対処の要点:
- Path に追加するのは実行ファイルが入っているフォルダ
- 追加後は新しいターミナルを開き直す
- 管理者権限が不要なら、まずはユーザー環境変数側で追加する
ケース2: Python 仮想環境の中では動くが、外では動かない
これは正常なこともあります。venv の有効化で、その環境の bin または Scripts が PATH の先頭に入るからです。
確認例:
python -m venv .venv
source .venv/bin/activate
command -v python
command -v pip
Windows PowerShell なら:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
where python
そのプロジェクト専用のコマンドなら、毎回グローバルな PATH に足さないほうが管理しやすいです。仮想環境を有効化して使う、あるいはフルパスで呼ぶほうが事故が少なくなります。
ケース3: スクリプトを置いたのに実行できない
自作スクリプトで起きやすいパターンです。
確認点:
- ファイル先頭に shebang があるか
- 実行権限があるか
PATHに入れたのがディレクトリか- 改行コードや拡張子が実行環境に合っているか
最小例:
#!/usr/bin/env bash
echo "hello"
保存後:
chmod +x hello
./hello
./hello では動くのに hello では動かないなら、ほぼ PATH の問題です。
ケース4: 同じ名前のコマンドが複数あり、意図したものが動かない
これは「見つからない」と逆方向のトラブルですが、原因はやはり検索順です。Bash は PATH の先頭側から探すので、同名コマンドが複数あると、先に見つかったほうが使われます。
確認例:
type -a python
Windows:
where python
複数出るなら、順序を見直します。特に次の組み合わせは混線しやすいです。
- OS 標準の Python と自前インストールの Python
- 複数の Node.js 管理ツール
- 社内配布ツールと手元の旧版 CLI
入力例と出力イメージ
エラー時の典型例です。
$ mytool
zsh: command not found: mytool
このときの確認:
$ command -v mytool
# 何も返らない
$ echo "$PATH"
/usr/local/bin:/usr/bin:/bin
仮に mytool が ~/tools/bin/mytool にあるなら、修正はこうなります。
export PATH="$HOME/tools/bin:$PATH"
source ~/.zshrc
command -v mytool
期待される状態:
/Users/yourname/tools/bin/mytool
この流れを覚えておくと、対象が python でも aws でも npm でも応用できます。
よくある失敗と直し方
短く整理すると、初心者が詰まりやすいのは次の点です。
- ファイルではなくディレクトリを
PATHに入れる - 設定を書いたあと、新しいシェルで反映を確認する
- 今使っているシェルが
bashかzshかを確認する - 仮想環境の内外で結果が変わることを前提にする
- 絶対パスで動くかを先に試す
NG例:
export PATH="$HOME/tools/bin/mytool:$PATH"
改善例:
export PATH="$HOME/tools/bin:$PATH"
NG例:
~/.bashrcを修正したのに、実際はzshを使っている
改善例:
echo "$SHELL"
関連ツールと代替手段
毎回 PATH を触る以外にも方法はあります。
フルパスで実行する
一時的な確認には最短です。
/Users/name/tools/bin/mytool
これで動けば、インストール失敗ではなく検索経路の問題だと切り分けられます。
プロジェクト単位の環境を使う
Python なら venv、Node.js ならバージョン管理ツールやプロジェクトローカル実行を使うと、グローバルな PATH 汚染を減らせます。
シェル組み込みで確認する
Linux/macOS では which より command -v や type -a のほうが、関数や組み込みコマンドも含めて確認しやすい場面があります。
実務での見方
業務環境では、command not found は単なる初歩的ミスではありません。次のような局面で頻繁に出ます。
- 開発端末を新しくした直後
- CI とローカルで実行結果が違うとき
- 社内配布 CLI の導入直後
- Python 仮想環境を切り替えたあと
- PowerShell と Git Bash を行き来するとき
ここで重要なのは、「コマンドがない」のか、「今の環境から見えない」のかを分けて考えることです。前者はインストール作業、後者は PATH と起動環境の整理で解決します。
まとめ
command not found に出会ったら、まず見るべき順番は決まっています。
PATHに対象ディレクトリが入っているかcommand -v/type -a/whereで実体を引けるか- 絶対パスなら動くか
- 仮想環境やシェル設定の違いがないか
- 実行権限や設定反映漏れがないか
この順で確認すれば、無駄に再インストールを繰り返す前に原因へたどり着けます。次に同じエラーが出たときは、コマンド名そのものではなく、そのコマンドを今のシェルがどう探しているかを見てください。
