Coding Agents & Terminal · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: ./setup.sh fails with Permission denied but bash setup.sh works (missing +x) —— Trove problem library

Verified 2026-08-29bash: ./script.sh: Permission denied — the script lacks the execute bit; chmod +x and run.

Quick fix

# One-liner: add the execute bit, then run directly
chmod +x setup.sh && ./setup.sh

What you will run into

A script copied from Windows or extracted from an archive fails with Permission denied when run as ./setup.sh, but bash setup.sh runs fine.

You think the file is corrupt or the system refuses to execute it — it's just that the script lacks the execute bit (x); Linux's permission model differs from Windows.

Why this happens

Linux uses the "execute bit" to decide whether a file can be run directly:

  • ./script.sh takes the "direct execution" path; the kernel requires the x bit;
  • bash script.sh passes the file as an argument for bash to read, no x bit needed — so the same file behaves differently depending on how you invoke it.

New files default to 644 (no execute bit); copying from Windows (FAT/exFAT/network drives) or extracting zips often loses the x bit; misconfigured core.fileMode in git repos can also drop it.

Linux runs a script via two paths: ./script.sh is "direct execution" — the kernel checks the x bit, then reads the shebang to find the interpreter;

bash script.sh is "interpreter reads the file" — bash just takes the file as an argument and does not check the execute bit.

That is why the same file behaves differently depending on how you call it.

The execute bit is file metadata (mode bits); new files default to 644 (no x); copying from Windows (FAT/exFAT/network drives do not support POSIX permissions) or extracting from zip (zip does not store the execute bit) commonly drops it;

git losing x on checkout is core.fileMode misconfiguration.

Deterministic takeaway: Permission denied + file exists = missing x — chmod +x fixes it; on WSL mount drives (/mnt/c) chmod is ineffective (drvfs does not support it) → copy into the WSL filesystem then chmod; after zip extraction, apply chmod +x uniformly;

in git the x bit is versioned — git update-index --chmod=+x <file> or fix core.fileMode; fixed diagnostic: ls -l shows the mode — no x in the first column confirms it.

Step by step

1. Confirm it's a permission issue — Required

ls -l setup.sh

Permission bits -rw-r--r-- (no x) → that's the problem (measured: after chmod 644, ./nox.sh reported Permission denied, exit=126).

2. Add the execute bit — Required

chmod +x setup.sh

3. Run again — Required

./setup.sh

Measured: after chmod +x normal output, exit=0.

4. Batch / prevention — Required

chmod +x scripts/*.sh
  • Before git commit, confirm git ls-files -s shows 100755 (executable);
  • After unzipping, add x as needed;
  • For Windows-mounted drives, handle core.fileMode as needed (keeping it true is usually more stable).

How to confirm it works

./setup.sh

No more Permission denied and normal execution means success (measured: bash nox.sh also runs, exit=0 — when you don't want to change permissions, invoking via an explicit interpreter works).

Other environments

EnvironmentNotes
WSL UbuntuSame as native Linux; add chmod +x
Files copied from WindowsFAT/exFAT/network drives don't carry the execute bit; always check after copying in
zip extractionunzip often drops the x bit; add as needed
git reposcore.fileMode=false lets x-bit changes go unsynced; keep it true
One-offbash script.sh / python3 app.py explicit interpreter invocation needs no x bit

Symptom

$ ./setup.sh
bash: ./setup.sh: Permission denied
  • ls -l shows -rw-r--r-- (no x).
  • bash setup.sh works, ./setup.sh fails.
  • Common after copying from Windows, unzipping archives, or creating new files.

Cause

  1. Linux uses the execute bit; new files default to 644 (no x).
  2. ./script.sh is "direct execution" (needs x); bash script.sh just reads the file (no x needed).
  3. Windows copies (FAT/exFAT/network), zip extraction and misconfigured git core.fileMode often drop the bit.

Solution

  1. chmod +x setup.sh then ./setup.sh.
  2. Or run via interpreter: bash setup.sh / python3 app.py.
  3. Batch: `chmod +x site docs
  4. Prevention: keep git ls-files -s mode 100755; restore x after unzip; keep core.fileMode true.
Verification Evidence
  • Local (WSL Ubuntu, 2026-08-29):
  • Repro 1: chmod 644 + ./nox.sh → Permission denied, exit=126 — matches user error.
  • Repro 2: bash nox.sh → runs, exit=0.
  • Fix: chmod +x → runs, exit=0.

Evidence details kept locally (2026-08-29)

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

bash

Bundled solutions (combos)

This problem is part of the following verified bundles.

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://stackoverflow.com/questions/18960689/ubuntu-says-bash-program-permission-denied

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk