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.

Published ~5 min read
On this page

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 chmod calculator translates between the letters and the numbers: rwxr-xr-x is 755, rw-r--r-- is 644.

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, so 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.

Related articles

All troubleshooting

Exit code 127: 'command not found' in scripts, cron, sudo and Docker

127 means the shell could not find the command. Why it happens in cron, sudo, systemd, npm scripts and Docker, how 126 differs, and a PATH checklist.

bad interpreter: No such file or directory, even though the file is right there

Windows line endings, a wrong shebang or a missing ELF loader make Linux say 'No such file or directory' for a file that exists. Find which one and fix it.

Permission denied while trying to connect to the Docker daemon socket: add your user to the docker group

Your user cannot open /var/run/docker.sock. Add it to the docker group safely, fix snap, rootless Docker and CI runners, and why chmod 666 is wrong.

Read-only file system: why Linux stops writing, and how to repair or remount safely

Read-only file system (EROFS) means the kernel blocks writes: a deliberate ro mount, or ext4 errors. Check findmnt and dmesg, then fsck offline before remount.

chmod command: 777, 755, +x and recursive, explained properly

What chmod 777, 755 and +x actually set, octal vs symbolic mode, chmod -R without breaking directories, and why chmod 777 is almost never the right fix.

Types of shell in Linux: sh, bash, dash, zsh, fish, ksh and tcsh compared

Types of shell in Linux compared: sh, bash, dash, zsh, fish, ksh, tcsh. Check which shell you use, change it with chsh, and write portable scripts.

How to run a .sh file in Linux: chmod +x, ./script.sh, bash, sh and source

Run a .sh file in Linux: chmod +x, then ./script.sh, or bash script.sh without chmod. What sh and source change, and fixes for Permission denied and CRLF.