Bash error: "Permission denied"

"Permission denied" on a Bash script usually means it is not executable. Fix it with chmod +x, check the shebang, and rule out a noexec mount.

Error String

bash: ./script.sh: Permission denied

Tldr

"Permission denied" when executing a file almost always means the execute bit is not set. Run "chmod +x script.sh" and try again. If it still fails, check the shebang line and whether the filesystem is mounted noexec.

Cause

To run a file as a program, the user invoking it needs the execute permission on that file. New files created by editors, downloaded with curl, or extracted from tarballs often lack +x. A less common cause is mounting /tmp or a removable disk with the noexec option, which disables execution regardless of the file mode.

Repro

$ ./deploy.sh
bash: ./deploy.sh: Permission denied

$ ls -l deploy.sh
-rw-r--r--  1 you  staff  142 Jun 16 10:00 deploy.sh   # no x bit

Fix

# Add execute for the owner (and optionally group/others)
chmod +x deploy.sh
./deploy.sh

# Or run it explicitly with bash, which only needs read permission:
bash deploy.sh

# If chmod doesn't help, the filesystem may be noexec:
mount | grep "$(df . | awk 'NR==2 {print $1}')"
# Look for "noexec" in the options. Move the script to a normal mount.

Explanation

Executing a script via "bash script.sh" bypasses the +x check because bash itself reads the file. That is a useful workaround but it skips the shebang too, so the script runs under whichever bash is on your PATH. Setting +x and running it directly honors the #! line, which is usually what you want.

Faq

Q

I ran chmod +x and still get the error — why?

A

Three common reasons: (1) the filesystem is mounted noexec — check `mount`; (2) the shebang points to a path that does not exist, which surfaces as "no such file or directory" but sometimes as permission denied; (3) on macOS, files downloaded from the web carry a quarantine xattr — run `xattr -d com.apple.quarantine script.sh`.

Q

Should I chmod 777?

A

No. chmod 755 (rwxr-xr-x) is the right default for a script you own. 777 makes it writable by everyone, which is a security risk on multi-user systems.

Q

Why is the script executable but I still cannot read it?

A

You need read AND execute on Linux — the kernel mmaps the file to run the interpreter. Use chmod u+rx to grant both.