Gradle「./gradlew: Permission denied」の原因と直し方
./gradlew: Permission denied は、gradlew に実行権限を付ければ直る。
Windows で追加した gradlew は実行ビットなしで Git に記録されるので、git update-index --chmod=+x で記録し直す。
公開:
要約
Gradle Wrapper の gradlew を実行すると、Gradle が動く前にシェルが止める。
Gradle 9.8.1 の gradle wrapper で作った gradlew から実行ビットを外して、bash で実行すると次のように出た。
$ ./gradlew build
bash: ./gradlew: Permission denied
$ ls -l gradlew
-rw-r--r-- 1 user user 8656 Oct 20 01:01 gradlew./gradlew: Permission denied は、gradlew に実行権限が無いという意味だ。
Gradle の設定やバージョンの問題ではない。
終了コードは 126 になる。gradlew はシェルスクリプトなので、実行ビット(x)が無いと ./gradlew の形では起動できない。
手元では動くのに CI だけで落ちるなら、Git に記録されている gradlew のモードを疑う。
公式ドキュメントのとおり Wrapper のファイルはリポジトリにコミットして共有するものなので(Gradle Wrapper(新しいタブで開く))、記録された時点で実行ビットが落ちていると、clone したすべての環境で同じエラーになる。
解決策
1. 手元で実行権限を付ける
chmod +x gradlew
./gradlew build2. 実行ビットを Git に記録する
CI で落ちる場合は、手元の chmod だけでは直らない。git update-index --chmod=+x で、Git に記録されているモードを変えてコミットする(git-update-index(新しいタブで開く))。
Windows の Git(Git for Windows 2.48)でも、この方法で 100755 に変わった。
git update-index --chmod=+x gradlew
git ls-files -s gradlew
git commit -m "gradlew を実行可能にする"
git pushgit ls-files -s gradlew の先頭が 100644 から 100755 に変われば記録できている。
コミットには mode change 100644 => 100755 gradlew と出る。
この後に clone し直した gradlew は -rwxr-xr-x になり、./gradlew --version が通った。
3. 権限を変えられないときは sh から起動する
読み取り専用の場所などで権限を変えられないときは、sh に gradlew を渡して起動する。
実行ビットの無い gradlew でも、sh gradlew --version は終了コード 0 で通った。
sh gradlew buildCI の設定に chmod +x gradlew のステップを足しても動くが、それは毎回の一時しのぎになる。
リポジトリ側の記録を直しておけば、どの環境でも ./gradlew のまま動く。
よくある原因
- Windows でコミットした。
Windows の Git では、git initやgit cloneのときにcore.fileModeがfalseに設定される(Git for Windows 2.48 で確認)。
この設定のまま新しく追加したファイルは、ディスク上で実行可能かどうかに関係なく100644(実行ビットなし)で記録される。
Linux の Git でcore.fileMode=falseにしてgradlewを追加したところ、実行可能なgradlewでも100644で記録された。 - それを clone した。
記録が100644なら、Linux や macOS、GitHub Actions のような CI で clone したgradlewは-rw-r--r--になる。 - 手元で実行ビットが外れた。
ファイルのコピーや展開の仕方によっては、実行ビットが付かないことがある。
core.fileMode は、作業ツリーのファイルの実行ビットを Git が信用するかどうかの設定である(git-config(新しいタブで開く))。