You wrote a script. You ran chmod +x script.sh. You try ./script.sh. And Linux spits back Permission denied. Infuriating, right? This happens to everyone at some point. The good news: it's usually a quick fix. The bad news: there are three different culprits, and they all show the same error. Let's knock them out one by one.
The 30-Second Fix: Check for the Shebang
This is the most common cause, and it's easy to miss. If your script doesn't start with a shebang line (#!/bin/bash or similar), the kernel has no idea what interpreter to use. It tries to execute the file as a binary, fails, and says Permission denied even though the file has execute permissions.
Open the script in a text editor and check the very first line. It should look like:
#!/bin/bash
Or, if you're writing a Python script:
#!/usr/bin/env python3
If it's missing, add it. Save the file. Try running it again. That's it. I've seen this trip up people who've used Linux for years – we've all been there.
The 5-Minute Fix: Check Mount Options and File System
If the shebang is there and you still get Permission denied, the next suspect is the file system itself. Some mounts are set with the noexec option. That means no files on this drive can be executed, regardless of permissions. This is common on /tmp, on removable drives, and on some corporate servers.
Check your mount options with:
mount | grep /path/to/your/directory
For example, if your script is in /home/you/scripts:
mount | grep /home
Look for noexec in the options. If it's there, that's your problem. The fix is to move the script to a partition that allows execution, like your home directory usually does. You can also remount the partition with exec, but that's a bigger change and might not be allowed on a system you don't control.
Also, check if you're on a filesystem like NTFS or FAT32. These don't support Unix-style execute permissions properly. If you're running a script from a Windows-mounted drive, copy it to your home directory first. I've seen this bite people who keep scripts on a shared drive.
The 15-Minute Fix: Inspect File Ownership and ACLs
If the shebang is fine and the mount allows execution, then we're looking at ownership or Access Control Lists (ACLs). First, check who owns the file:
ls -l script.sh
You'll see something like -rwxr-xr-x 1 root root. If the owner is root and you're not root, you won't be able to execute it unless you use sudo (which you shouldn't do for a personal script).
If the owner is you, but the permissions don't include execute for the user, run:
chmod u+x script.sh
That's the user-only execute bit. Sometimes people run chmod +x but miss that they're not the file owner. Check with id to confirm your username.
Next, check for ACLs. These can override standard permissions. Use:
getfacl script.sh
If you see a line like mask::r-x, that mask is limiting effective permissions. You might have execute on the user, but the mask blocks it. To fix that:
setfacl -m u::rwx script.sh
That resets the user ACL entry. It's a rare issue, but I've seen it on systems with complex user management, especially in enterprise environments.
One more quick test: check if the file has a weird extended attribute that blocks execution. Run:
lsattr script.sh
If you see an i (immutable) flag, that prevents any changes, including execution. Remove it with sudo chattr -i script.sh. That's rare, but it's a real thing that happens when someone accidentally sets it.
Still Stuck? Try Running with bash Explicitly
If you're in a hurry and just need the script to run, you can bypass the execute permission entirely:
bash script.sh
That works for Bash scripts. For Python, use python3 script.py. This doesn't fix the underlying issue, but it gets you moving. I'd still go back and figure out why ./script.sh fails, because you'll want that to work eventually.
Real-world trigger: You just downloaded a script from the internet, did
chmod +x, and it won't run. Nine times out of ten, it's the missing shebang because Windows text editors strip or never add it. Always check that first.
The key takeaway: Permission denied doesn't always mean bad permissions. It can mean the OS can't figure out how to run the file. Start with the shebang, then look at mount options, then dig into ownership and ACLs. You'll have it running in no time.