command not found は、シェルが「その名前のコマンドを、PATH(コマンドを探すディレクトリの一覧)のどこにも見つけられなかった」ときのエラーです。 原因は大きく、「入っていない」「入っているが PATH に無い」「見つかったが実行できない」の3つに分かれます。

まず、次の3つのコマンドで状況を確かめます。

command -v mytool          # 見つかれば場所を表示。見つからなければ何も出ない
echo "$PATH" | tr ':' '\n' # 探す場所の一覧を1行ずつ
ls -l ~/.local/bin/mytool  # 入れたはずの場所に、実際にあるか
エラー文 原因 対処
bash: foo: command not found 入っていない、または PATH に無い インストール、または PATH に追加
zsh: command not found: foo 同上(zsh の書き方) 同上
sudo: foo: command not found sudo が PATH を secure_path に置き換えた sudo "$(command -v foo)"
bash: ./x.sh: Permission denied 実行権限が無い chmod +x x.sh
cannot execute: required file not found/bad interpreter シェバンの行が CRLF、またはインタプリタが無い sed -i 's/\r$//' x.sh
$'\r': command not found スクリプトや .bashrc の改行が CRLF 同上
bash: /old/path/foo: No such file or directory bash が覚えていた場所から消えた hash -r

確認環境:Ubuntu 24.04・bash 5.2.21・zsh 5.9・dash(/bin/sh)・sudo 1.9.15p5。改行コードのエラー文の違いは、Ubuntu 22.04 の bash 5.1.16 のバイナリを取り出して比べました。この記事のエラー文は、どれも手元で再現したものです。nvm・pyenv・Homebrew の設定は、それぞれの公式ドキュメントに基づいています(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「command not foundの直し方|PATHの確認方法と原因別の対処表」

bash・zsh・sh でエラー文が違う

同じ「無いコマンド」を実行しても、シェルによって書き方が違います。検索するときは、自分のシェルの書き方で探すと見つけやすくなります。

シェル 対話(プロンプトで入力) -c やスクリプトの中
bash bash: foo123: command not found bash: line 1: foo123: command not found
zsh zsh: command not found: foo123 zsh:1: command not found: foo123
sh(Ubuntu は dash) — sh: 1: foo123: not found
bash のスクリプト — ./t1.sh: line 3: foo123: command not found

zsh は「command not found」が先、コマンド名があとです。bash は逆です。macOS の既定のシェルは zsh なので、Mac では zsh の形で出ます。

どのシェルでも、終了ステータス($?)は 127 でした。 bash のマニュアルでは、「コマンドが見つからないときは 127、見つかったが実行できないときは 126」とされています。

$ foo123
bash: foo123: command not found
$ echo $?
127

終了ステータスの一覧は、関連記事「シェルスクリプトの終了ステータス $?とexitコード一覧・判定方法」で扱っています。

type・command -v・which・echo $PATH での切り分け

見つからないときに、何が出るかを比べました(mytool は、PATH に無いディレクトリに置いたコマンド)。

コマンド bash zsh 向いている場面
type mytool bash: type: mytool: not found mytool not found エイリアス・関数・組み込みかも分かる
command -v mytool 何も出ない(終了ステータス 1) 何も出ない(1) スクリプトでの存在チェック
which mytool 何も出ない(1) mytool not found 実行ファイルの場所だけ
whence -p mytool(zsh) — 何も出ない(1) zsh で実行ファイルの場所

PATH に入れたあとは、どれも場所を返しました。

$ type mytool
mytool is /home/you/tools/mytool/bin/mytool
$ command -v mytool
/home/you/tools/mytool/bin/mytool
$ type -a ls
ls is /usr/bin/ls
ls is /bin/ls
$ type cd
cd is a shell builtin

type -a は、PATH の中にある同じ名前のコマンドを全部出します。 「別の版が先に見つかっている」ときの確認に使えます。Ubuntu の which は外部コマンドで、エイリアスや関数は分かりません。zsh の which はシェルの組み込みで、見つからないと mytool not found と出しました。

スクリプトの中でコマンドの有無を調べるなら、POSIX で決まっている command -v が使えます。

if ! command -v jq >/dev/null 2>&1; then
  echo "jq がありません。sudo apt install jq で入れられます" >&2
  exit 127
fi

PATH を1行ずつ見る

$ echo "$PATH" | tr ':' '\n'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin

PATH は左から順に探されます。 入れたはずのディレクトリが一覧に無ければ、原因は「PATH に無い」です。PATH の設定方法そのものは、関連記事「Linux環境変数PATHの設定方法|exportと.bashrcの使い分け早見表」で扱っています。

原因別の対処表

原因 確かめ方 対処
① 入っていない・綴りが違う apt list --installed 2>/dev/null | grep 名前 など インストールする。大文字・小文字も確かめる
② 入っているが PATH に無い ls 入れた場所、echo $PATH PATH に追加する
③ PATH の書き方を間違えた echo "$PATH" に ~ が残っている、ls も見つからない 書き方を直す(下の表)
④ 設定ファイルが読まれていない bash -lc 'command -v 名前' で変わるか 読まれるファイルに書く
⑤ sudo だけ見つからない sudo を付けたときだけ失敗 フルパスで実行する
⑥ pip --user・npm -g・nvm・pyenv 入った場所を調べる その場所を PATH に追加する
⑦ カレントディレクトリのスクリプト ls ./x.sh はある ./x.sh と書く
⑧ 実行権限が無い ls -l に x が無い chmod +x
⑨ 改行コードが CRLF file x.sh に with CRLF sed -i 's/\r$//' x.sh
⑩ bash が前の場所を覚えている hash に前の場所 hash -r(zsh は rehash)

① 入っていない・綴りが違う

コマンド名とパッケージ名が違うことがあります(例:dig は Ubuntu では bind9-dnsutils)。Ubuntu 24.04 では、python という名前のコマンドは python-is-python3 のパッケージで入ります。Docker の小さなイメージには、ping・ps・vim などが入っていないことも多くあります。

② PATH に無い

入れたディレクトリを、PATH の先頭か末尾に足します。

export PATH="$HOME/opt/bin:$PATH"   # 今のシェルだけ

次に開くシェルでも使うには、設定ファイル(④)に書きます。

③ PATH の書き方を間違えた

手元で再現した、よくある書き間違いです。

書いたもの 結果 正しい書き方
export PATH="~/bin:$PATH" PATH に ~/bin と文字のまま入り、見つからない export PATH="$HOME/bin:$PATH"
PATH = "$HOME/bin:$PATH" bash: line 1: PATH: command not found = の前後に空白を入れない
export PATH=/opt/tool/bin(:$PATH が無い) ls まで command not found export PATH=/opt/tool/bin:$PATH

"~/bin" のように、~ を引用符で囲むと展開されません。 引用符の中では $HOME を使います。手元では、引用符なしの ~/bin は /home/you/bin に展開されましたが、引用符つきは ~/bin のままでした。

PATH を上書きして ls も動かなくなったときは、フルパスで直せます。

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/usr/bin/vi ~/.bashrc   # 書き間違えた行を直す

④ シェルの設定ファイルが読まれていない

.bashrc に PATH を書いても、読まれない起動のしかたがあります。 bash と zsh で、どのファイルが読まれるかを、手元で1つずつ確かめました。

起動のしかた bash が読む(ホームのもの) zsh が読む
ログインシェル(SSH でログイン、bash -l) .bash_profile・.bash_login・.profile の最初に見つかった1つ .zshenv・.zprofile・.zlogin
対話の非ログイン(ターミナルで bash を起動) .bashrc .zshenv・.zshrc
非対話(bash -c・スクリプト・cron) 読まない(BASH_ENV があればそれ) .zshenv だけ

再現した結果です(mytool の PATH を、そのファイルに書いた場合)。

PATH を書いた場所 起動 結果
.profile だけ bash -lc 見つかった
.profile+空の .bash_profile がある bash -lc 見つからない(.profile が読まれない)
.bashrc の末尾(Ubuntu の初期の .bashrc) bash -c 見つからない
同上 bash -lc 見つからない
同上 対話の bash 見つかった
.zshrc zsh -c・zsh -lc 見つからない
.zshrc zsh -ic 見つかった
.zshenv zsh -c 見つかった

.bash_profile があると、.profile は読まれません。 何かのインストーラが .bash_profile を作ると、それまで .profile に書いていた PATH が急に効かなくなります。.bash_profile から .profile を読み込むと、両方が効きます。

# ~/.bash_profile
[ -f "$HOME/.profile" ] && . "$HOME/.profile"

Ubuntu の初期の .bashrc は、先頭で「対話でなければ何もしない」で終わります。 そのため、末尾に追記した PATH は、ログインシェルから読み込まれても、対話でなければ効きませんでした。

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

cron や ssh ホスト コマンド のような「対話でない」実行で見つからないときは、PATH を .profile(zsh なら .zshenv)に書くか、スクリプトの中で PATH を設定するか、フルパスで書きます。

設定ファイルを直したあとは、今開いているシェルには反映されません。 source ~/.bashrc を実行するか、ターミナルを開き直します。

エイリアス(ll など)も、.bashrc に書いたものは、スクリプトの中では使えません。関連記事「Linux alias設定と.bashrcの書き方|おすすめエイリアス50選」で扱っています。

⑤ sudo を付けると見つからない(secure_path)

自分では動くのに、sudo を付けると見つからないのは、sudo が PATH を決まった値に置き換えるためです。

$ mytool
mytool 1.0
$ sudo mytool
sudo: mytool: command not found

Ubuntu の /etc/sudoers には、次の行がありました。

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

sudo の中では、この一覧だけが探されます。 ~/.local/bin や nvm の Node.js はここに無いので見つかりません。手元で動いた直し方は2つです。

sudo "$(command -v mytool)"      # 自分の PATH で見つけたフルパスを渡す
sudo env "PATH=$PATH" mytool     # 自分の PATH を引き継ぐ

secure_path を書き換えるより、フルパスで渡すほうが影響が小さく済みます。 su と sudo の違いは、関連記事「Linuxのsuとsudoの違い|su -・sudo -i・-sの比較表」で扱っています。

⑥ pip --user・npm -g・nvm・pyenv の場所

パッケージ管理ツールは、OS の標準とは別の場所にコマンドを入れることがあります。 その場所が PATH に無いと、インストールが成功しても command not found になります。

入れ方 コマンドが入る場所 PATH に足すもの
pip install --user ~/.local/bin(python3 -m site --user-base の下の bin) $HOME/.local/bin
npm install -g(prefix を変えた場合) npm prefix -g の下の bin 例:$HOME/.npm-global/bin
nvm ~/.nvm/versions/node/版/bin nvm が .bashrc などに書く行で設定
pyenv ~/.pyenv/shims eval "$(pyenv init - bash)" で設定
Homebrew(Apple シリコンの Mac) /opt/homebrew/bin eval "$(/opt/homebrew/bin/brew shellenv)"

pip は、PATH に無い場所に入れたときに警告を出していました。

WARNING: The script cowsay is installed in '/home/you/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed cowsay-6.1

そのあと cowsay を実行すると、bash: line 7: cowsay: command not found でした。Ubuntu の初期の .profile は、ログインした時点で ~/.local/bin があれば PATH に足します。 そのため、bash -lc で開き直すと見つかりました。初めて pip install --user したあとは、ログインし直すと PATH に入ります。

Ubuntu 24.04 などで pip install --user が externally-managed-environment で止まる場合は、関連記事「externally-managed-environmentの直し方|pip」で扱っています。

npm で、グローバルの場所を自分のホームに変えた場合も同じでした。

$ npm config set prefix "$HOME/.npm-global"
$ npm install -g cowsay
$ cowsay hi
bash: line 6: cowsay: command not found
$ export PATH="$HOME/.npm-global/bin:$PATH"
$ command -v cowsay
/home/you/.npm-global/bin/cowsay

npm install -g の権限エラーは、関連記事「npm EACCES: permission deniedの直し方」で扱っています。

nvm の README では、インストールのスクリプトが ~/.bashrc・~/.bash_profile・~/.zshrc・~/.profile のどれかに次の行を足すとされています。

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

インストール直後の nvm: command not found について、README には「ターミナルを開き直すか、source ~/.bashrc を実行する」とあります。この行は .bashrc に入ることが多いので、④の「対話でないと読まれない」と、⑤の sudo の両方で node: command not found になります。 nvm などの比較は、関連記事「Node.js バージョン管理|nvm・fnm・mise・Volta比較と実測」で扱っています。

pyenv の README の bash 向けの設定は次の3行で、~/.bashrc とログイン用のファイルの両方に書くよう案内されています。

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"

zsh では ~/.zshrc に書き、最後の行を eval "$(pyenv init - zsh)" にします。

⑦ カレントディレクトリのスクリプト

今いるディレクトリは、PATH に入っていません。 ファイルがあっても、名前だけでは見つかりません。

$ hello.sh
bash: line 1: hello.sh: command not found
$ ./hello.sh
hello

スクリプトの実行方法の違いは、関連記事「シェルスクリプトの実行方法4通りの違いとシェバンの意味 エラー別対処つき」で扱っています。

⑧ 実行権限が無い

実行権限(x)が無いと、command not found ではなく Permission denied になり、終了ステータスは 126 でした。

シェル エラー文 $?
bash bash: line 1: ./hello.sh: Permission denied 126
zsh zsh:1: permission denied: ./hello.sh 126
chmod +x hello.sh   # 実行権限を付ける
bash hello.sh       # または、bash に渡せば権限が無くても動く

権限の数字の意味は、関連記事「chmodの755と644の意味|用途別パーミッション早見表」で扱っています。

⑨ 改行コードが CRLF(Windows で作ったスクリプト)

Windows のエディタで保存したスクリプトは、行末が CRLF(\r\n)になることがあります。 1行目の #!/bin/bash の後ろに \r が付き、「/bin/bash\r というインタプリタ」を探してしまいます。

このときのエラー文は、bash の版で違いました。

シェル・版 エラー文(対話で実行) $?
bash 5.2.21(Ubuntu 24.04) bash: ./crlf.sh: cannot execute: required file not found 127
bash 5.1.16(Ubuntu 22.04) bash: ./crlf.sh: /bin/bash^M: bad interpreter: No such file or directory 126
zsh 5.9 zsh: ./crlf.sh: bad interpreter: /bin/bash^M: no such file or directory 127

bash 5.2 では bad interpreter と出ず、^M も表示されません。 「ファイルはあるのに required file not found」と出たら、まず改行コードを疑います。シェバンのインタプリタが本当に無い場合(#!/usr/local/bin/bash など)も同じエラー文でした。#!/usr/bin/env python2 で python2 が無いときは /usr/bin/env: 'python2': No such file or directory でした。

bash crlf.sh のように bash に直接渡すと、1行目は無視されますが、中の空行やコマンドの行で別のエラーになりました。

crlf2.sh: line 2: $'\r': command not found
ls: cannot access '/tmp'$'\r': No such file or directory

> /dev/null の行が CRLF だと、/dev/null ではなく /dev/null\r という名前のファイルが作られました。 root で動かすと /dev の中にファイルが残るので、見つけたら消しておきます。

確かめ方と直し方です。

file crlf.sh
# crlf.sh: Bourne-Again shell script, ASCII text executable, with CRLF line terminators
cat -A crlf.sh | head -2
# #!/bin/bash^M$
sed -i 's/\r$//' crlf.sh   # CRLF を LF に(dos2unix crlf.sh でも可)

.bashrc を CRLF で保存した場合も、PATH が壊れました。 末尾の \r が、足したディレクトリの名前の一部になります。

bash: $'\r': command not found
$ command -v mytool || echo "(not found)"
(not found)
$ echo "$PATH" | cat -A
/usr/bin:/bin:/home/you/opt/bin^M$

詳しくは関連記事「bad interpreter: ^Mの直し方|改行コードCRLF」で扱っています。Git で CRLF にならないようにする設定は、関連記事「Git改行コード設定|autocrlfと.gitattributesの違い」で扱っています。

⑩ bash が前の場所を覚えている(hash)

bash は、一度見つけたコマンドの場所を覚えます(ハッシュ)。 コマンドを別のディレクトリに移すと、覚えた場所を見に行って失敗しました。

$ mt
mytool 1.0
$ hash
hits    command
   1    /home/you/tools/a/mt
$ mv tools/a/mt tools/b/mt
$ mt
bash: line 1: /home/you/tools/a/mt: No such file or directory
$ hash -r
$ mt
mytool 1.0

フルパスつきの No such file or directory は、この原因のことがあります。 hash -r で覚えた場所を消すか、新しいシェルを開きます。zsh では rehash です。

よくある質問

Q. Docker や CI だけで command not found になります。 A. 多くは「対話でないシェル」で動くため、.bashrc が読まれません(④)。Dockerfile では ENV PATH="/opt/tool/bin:${PATH}"、CI ではジョブの設定で PATH を足す方法があります。Go や Docker の executable file not found in $PATH は、関連記事「executable file not found in $PATHの直し方」で扱っています。

Q. Mac で Homebrew で入れたのに見つかりません。 A. Apple シリコンの Mac では、Homebrew は /opt/homebrew/bin に入ります。Homebrew のインストーラが案内する eval "$(/opt/homebrew/bin/brew shellenv)" を ~/.zprofile に書き、ターミナルを開き直します。

Q. PATH にディレクトリが入っているのに見つかりません。 A. echo "$PATH" | cat -A で、^M や空白が混ざっていないかを見ます(⑨)。ファイルに実行権限があるか(ls -l)、名前の大文字・小文字が合っているかも確かめます。

Q. which では見つかるのに、実行すると別のものが動きます。 A. エイリアスや関数が優先されている可能性があります。type -a コマンド名 で、エイリアス・関数・PATH の中の候補を全部出せます。

まとめ

  • command not found は PATH のどこにも無い。終了ステータスは 127
  • bash は bash: foo: command not found、zsh は zsh: command not found: foo、sh(dash)は sh: 1: foo: not found
  • 確かめるのは command -v・type -a・echo "$PATH" | tr ':' '\n'
  • PATH は "$HOME/bin:$PATH"。"~/bin" と書くと展開されない
  • .bash_profile があると .profile は読まれない。.bashrc は対話でないと読まれない
  • sudo は secure_path で探す。sudo "$(command -v foo)"
  • CRLF は bash 5.2 で cannot execute: required file not found、5.1 以前と zsh は bad interpreter

参考・出典

確認日はいずれも 2026年10月12日です。

  • GNU Bash マニュアル「Bash Startup Files」:https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
  • GNU Bash マニュアル「Exit Status」:https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
  • Zsh マニュアル「Startup/Shutdown Files」:https://zsh.sourceforge.io/Doc/Release/Files.html
  • sudoers マニュアル(secure_path):https://www.sudo.ws/docs/man/sudoers.man/
  • nvm README:https://github.com/nvm-sh/nvm/blob/master/README.md
  • pyenv README:https://github.com/pyenv/pyenv/blob/master/README.md
  • npm Docs「folders」(prefix と bin の場所):https://docs.npmjs.com/cli/configuring-npm/folders
  • Python Packaging User Guide「Installing packages using pip and virtual environments」:https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「command not foundの直し方|PATHの確認方法と原因別の対処表」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?