VMHeaven

Troubleshooting

bash: Permission denied — why your script will not run

Permission denied on a script usually means the execute bit is missing, or the file lives on a noexec mount. How to tell which, and fix both safely.

Updated 08 Aug 2026~5 min read

bash: ./script.sh: Permission denied almost never means you lack rights to the file’s contents — it means the file is not marked executable, or it lives on a filesystem mounted so that nothing on it can execute. Two very different fixes, so identify which one you have.

The usual cause: no execute bit

A freshly downloaded or newly written script has no x permission. Add it:

make it executable
chmod +x script.sh
./script.sh

Check what you have with ls -l. You want to see an x in the owner column:

read the bits
ls -l script.sh
# -rw-r--r--  → not executable
# -rwxr-xr-x  → executable

The workaround that always tells the truth

Call the interpreter directly. If this works but ./script.sh does not, the problem was definitely the execute bit, not the code:

run via the interpreter
bash script.sh
sh script.sh
python3 script.py

When chmod does not help: noexec mounts

/tmp, /dev/shm and some home partitions are frequently mounted noexec for security — nothing on them may run regardless of permissions. Check with:

is the mount noexec?
mount | grep -E '/tmp|/home'
# look for the word "noexec" in the options
  • Move the script to a normal path such as your home directory and run it there.
  • Or invoke the interpreter explicitly (bash /tmp/script.sh), which sidesteps the exec check.

A related trap: the shebang

If the script is executable but you get bad interpreter or a cryptic error, the first line may point at a missing interpreter or carry Windows line endings. Check and strip carriage returns:

fix CRLF line endings
head -1 script.sh          # should be e.g. #!/usr/bin/env bash
sed -i 's/\r$//' script.sh  # remove trailing \r from Windows editors

“Permission denied” on cd or a file you own

Entering a directory needs its execute bit; reading a file needs read on the file and execute on every directory above it. If cd is refused:

directory access
chmod +x /path/to/dir      # execute = "may traverse"
ls -ld /path /path/to /path/to/dir

Need a clean box to test permission-sensitive deploys without touching production? A throwaway KVM VPS spins up in about a minute and bills by the month.

Frequently asked

Why does 'bash script.sh' work but './script.sh' does not?

Calling the interpreter directly does not need the file's execute bit; running it as a program does. If the interpreter form works, add the execute bit with chmod +x.

chmod +x did not help — why?

The file is probably on a filesystem mounted noexec, such as /tmp or /dev/shm. Move it to your home directory, or invoke the interpreter directly.

Is it safe to remount /tmp without noexec?

Avoid it. noexec on /tmp is a deliberate defence against dropped payloads. Run the script from a normal path instead of weakening the mount.

More in Troubleshooting

See all