You're at the terminal, you type ./script.sh or cat /etc/shadow, and the shell spits back Permission denied. It's one of the most common Linux errors, and it's almost never a mystery. I've trained dozens of techs on this, and in 90% of cases, it's one of three things: file permissions, file ownership, or SELinux. Let's go through them from most to least likely.
Cause #1: File Permissions Don't Allow Your Access
The most common trigger is a missing execute bit on a script or a file that's not readable by your user. For example, you download a script from the internet, and it arrives with mode 644—owner can read/write, everyone else can only read. You try to run it, and boom, Permission denied.
First, check what the permissions actually are:
ls -l script.shYou'll see something like -rw-r--r--. The x bits are missing. To fix it, add the execute bit for the owner (and possibly for everyone, but that's your call):
chmod +x script.shThen run it with ./script.sh. If it still fails, check if the directory you're in has the right permissions. You need r and x on each directory in the path. If the directory is 711 (owner only), other users can't enter. To fix that, set chmod 755 /path/to/dir.
After applying chmod, run ls -l again. You should see the x bits now. That's your confirmation.
Cause #2: You Don't Own the File
Even if the permissions are wide open, if the file's owner is another user and the group doesn't grant you access, you're out of luck. This happens a lot with files copied from a USB drive or extracted from a tarball created by someone else.
Check the owner and group with ls -l. You'll see something like root root or alice staff. If you're not in that group, try to verify what groups you're in:
groupsIf the file is owned by root and you're not root, you have two options. If you have sudo privileges, change the ownership:
sudo chown yourname:yourgroup fileOr, if you only need to read it, change the group permissions on the file so everyone can read it:
sudo chmod o+r fileReal-world example: you mounted an NTFS drive and the files show as root-owned with rwx------. You can't get in. The fix is to remount the drive with the uid and gid options so your user owns the mount point. Or simply do sudo chown -R youruser:yourgroup /mnt/yourdrive.
After chown, ls -l will show your username. That's your sign it worked.
Cause #3: SELinux Is Blocking You
This one sneaks up on people, especially on CentOS, RHEL, or Fedora. You've set the right permissions, the file shows -rwxr-xr-x and you own it, but the system still says Permission denied. That's SELinux doing its job—sometimes a bit too well.
Check if SELinux is enforcing:
getenforceIf it says Enforcing, you've got a candidate. Look at the SELinux context for the file:
ls -Z fileYou'll see something like unconfined_u:object_r:user_home_t. If it's not the right type, SELinux blocks access. The quick test: set SELinux to permissive temporarily and try again. If it works, you've found your culprit.
sudo setenforce 0Then try your command. If it succeeds, you have two paths. The lazy one (don't do this on production): disable SELinux permanently. The right one: fix the context. For example, if you're running a web script from /var/www/html and it's labeled httpd_sys_content_t, you're fine. If it's user_home_t, change it:
sudo chcon -t httpd_sys_content_t /var/www/html/script.phpOr use restorecon to put it back to the default:
sudo restorecon -v /var/www/html/script.phpAfter restorecon, you'll see a message like restorecon: reset context .... That means it changed. Test your command again. If it works, you're done. Don't forget to set SELinux back to enforcing with sudo setenforce 1.
Quick-Reference Summary
| Cause | Check command | Fix command |
|---|---|---|
| Missing execute bit | ls -l file | chmod +x file |
| Wrong owner/group | ls -l file | sudo chown user:group file |
| SELinux context | ls -Z file | sudo restorecon -v file |
That's it. Start with ls -l, then check owner, then check SELinux. I've seen techs spend an hour on SELinux when it was just a missing execute bit. Always go in this order.