- 技術 💻
command not foundの直し方|PATHの確認方法と原因別の対処表
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期連続の黒字決算。