できない.dev

Bash で「Permission denied」が出てシェルスクリプトを実行できない

./script.sh が Permission denied になるのは、ファイルに実行ビットが立っていないか、置き場所が noexec でマウントされているかのどちらかである。chmod +x で実行ビットを付けるか、bash script.sh とインタプリタを明示して回避する。

公開: 更新:

実行例あり(2026-09-12 に実環境で検証)

要約

bash: ./script.sh: Permission denied は、スクリプトを実行しようとしたが実行権が無いときに出る。
文法エラーでもインタプリタの不在でもないので、まず ls -l で権限を見るのが最短である。

$ ./deploy.sh
bash: ./deploy.sh: Permission denied
$ ls -l deploy.sh
-rw-r--r-- 1 user user 512 Aug 10 09:00 deploy.sh

-rw-r--r-- に x が無い。
この状態でスクリプト名を直接叩くと、カーネルの execve が EACCES を返し、Bash がそれを Permission denied として表示する。
終了ステータスは 126 になる。

実行例

実行ビットの無い -rw-r--r-- のスクリプトを ./deploy.sh で起動すると Permission denied になり、終了コードは 126 が返った。
同じファイルでも bash deploy.sh とインタプリタを明示すれば動き、chmod +x で -rwxr-xr-x にしたあとは ./deploy.sh でもそのまま実行できている。

$ ls -l deploy.sh
-rw-r--r-- 1 root root 31 Sep 12 02:45 deploy.sh
$ ./deploy.sh
bash: line 1: ./deploy.sh: Permission denied
終了コード: 126
$ bash deploy.sh
deploy done
終了コード: 0
$ chmod +x deploy.sh
$ ls -l deploy.sh
-rwxr-xr-x 1 root root 31 Sep 12 02:45 deploy.sh
$ ./deploy.sh
deploy done
終了コード: 0

— 2026-09-12 時点の出力

検証環境

検証日
実行環境
ubuntu:24.04Ubuntu 24.04.4 LTS
バージョン
  • Bash 5.2.21

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. 実行ビットが立っていない: 一番多い。git clone した直後、unzip で展開した直後、Windows 側のエディタで作った直後などに起きる。
  2. #! 行のインタプリタ側に実行権が無い: スクリプトには x があるのに落ちる場合はこちらを疑う。
  3. 置き場所が noexec: /tmp を noexec でマウントしている環境や、外部メディア・一部のコンテナでは、実行ビットがあっても実行できない。
  4. 親ディレクトリに検索権が無い: ディレクトリの x はそこを通り抜ける権限を意味する。
    これが無いとファイルへ到達できない。
  5. 所有者が自分ではない: sudo を付けて展開・コピーした結果、root 所有の -rwx------ になっていると、自分では実行できない。

なお ./dir のようにディレクトリを実行しようとした場合は Is a directory になり、このエラーにはならない。
メッセージが Permission denied であるうちは、上の 5 つのいずれかである。

解決策

1. 実行ビットを付ける

ls -l deploy.sh              # 所有者が自分か、x があるかを見る
chown "$USER" deploy.sh      # 所有者が違うときだけ
chmod +x deploy.sh
./deploy.sh

+x は所有者・グループ・その他のすべてに実行権を足す(chmod の仕様(新しいタブで開く))。
自分だけに限定したいなら chmod u+x deploy.sh を使う。

2. 権限を変えずに実行する

bash deploy.sh
sh deploy.sh        # POSIX sh として動かしたい場合

インタプリタを明示すると、実行されるのは bash であってスクリプトファイルではないため、実行ビットが無くても動く。
読み取り権さえあればよい。
noexec なディレクトリでも通る。

3. noexec を確認する

mount | grep -E ' /tmp | on /mnt'

出力に noexec があれば、そこに置いたスクリプトは実行ビットがあっても実行できない。
ホームディレクトリなど別の場所へ移す。

4. 実行ビットを Git に記録する

git update-index --chmod=+x deploy.sh
git commit -m "make deploy.sh executable"

ローカルで chmod しても、実行ビットを commit していなければ他の開発者や CI では再び Permission denied になる。
Bash スクリプトをリポジトリに置くときはここまでやっておく。

この記事は役立ちましたか?