Linux shell / CLI linux permissions bash

Linux bash: Permission denied

Encountering "Permission denied" in Linux bash means your user lacks necessary file or directory permissions; this guide explains how to diagnose and fix it.

What This Error Means

When you see "Permission denied" in your Linux bash shell, it's the operating system telling you, quite directly, that you're attempting an action for which your current user account does not have the required access rights. This error is fundamental to Linux's security model, which is built on user and group permissions governing every file and directory in the system.

Fundamentally, every file and directory has three primary types of permissions:
* Read (r): Allows viewing the contents of a file or listing the contents of a directory.
* Write (w): Allows modifying or deleting a file, or creating/deleting files within a directory.
* Execute (x): Allows running a file as a program (if it's an executable script or binary) or traversing into a directory (meaning you can cd into it or access files inside it, even if you can't list its contents).

The "Permission denied" error indicates that one of these necessary permissions is missing for the user attempting the action.

Why It Happens

The Linux filesystem enforces a strict hierarchy of ownership and permissions. Each file and directory is owned by a specific user and belongs to a specific group. Permissions are then set for three categories: the owner of the file, the group that owns the file, and others (everyone else).

When you try to, for example, run a script, read a log file, or write to a configuration file, the system checks:
1. Who is trying to perform the action? (Your current user ID).
2. Who owns the target file/directory?
3. What group does the target file/directory belong to?
4. What permissions are set for the owner, group, and others on that target?

If your user ID is not the owner, not a member of the owning group, and the "others" permissions do not grant the required access, or if the "execute" bit isn't set on a script you're trying to run, then "Permission denied" is your inevitable result. In my experience, this is one of the most frequent hurdles for newcomers and a recurring check for seasoned engineers.

Common Causes

"Permission denied" is almost always a direct consequence of an improper permission setting. Here are the most common scenarios I've encountered:

  • Missing Execute Permission on a Script: This is perhaps the most common. You download or create a script (.sh, Python, Perl) and try to run it (e.g., ./myscript.sh), but it hasn't been marked as executable. The system sees it as just another text file.
  • Missing Read Permission on a File: Attempting to view the content of a file (cat, less, more) for which your user or group lacks read access. This is common with sensitive configuration files or log files that are often restricted.
  • Missing Write Permission on a File or Directory: Trying to save changes to a file, create a new file, or delete an existing file in a directory where you don't have write access. This often happens in system directories (like /usr/local/bin or /etc) without sudo.
  • Incorrect Ownership: A file or directory might be owned by a different user (e.g., root, www-data) and your user isn't part of that group, nor do "others" have the necessary permissions. This frequently occurs when files are copied from a root-privileged operation or deployed by a different service user.
  • User Not in Correct Group: You might expect access to a file because it belongs to a certain group, but your user account hasn't been added to that group. This is common for shared resources like Docker sockets or specific hardware access groups.
  • SELinux or AppArmor Restrictions: On systems with enhanced security modules like SELinux (e.g., CentOS, Fedora) or AppArmor (e.g., Ubuntu), even if standard file permissions appear correct, the security module might be preventing access based on its own policies. I've seen this in production when deploying services where the process context wasn't properly labelled, leading to unexpected access denials.
  • Read-Only Filesystem: Less common for a direct "Permission denied" message (often yields "Read-only file system"), but if you're trying to write to a volume that has been mounted as read-only, you will be denied. This can happen during system recovery or when external media is mounted in a restricted fashion.

Step-by-Step Fix

Addressing "Permission denied" involves a systematic approach to identify the root cause and apply the correct fix.

  1. Identify the Target and Action:

    • What file or directory are you trying to access? (e.g., /home/ingrid/my_script.sh, /var/log/app.log, /opt/myapp/config/)
    • What action are you trying to perform? (execute, read, write, list directory contents?)
  2. Check Permissions and Ownership:

    • Use ls -l on the target to view its permissions, owner, and group.
      bash ls -l /path/to/problematic_file_or_directory
    • Example Output Interpretation:
      -rwxr-xr-- 1 ingrid devgroup 1024 Jan 15 10:30 my_script.sh
      • The first character - means it's a regular file (d for directory).
      • rwxr-xr-- defines permissions:
        • rwx: Owner (ingrid) has read, write, and execute.
        • r-x: Group (devgroup) has read and execute.
        • r--: Others have only read access.
      • 1: Number of hard links.
      • ingrid: The owner of the file.
      • devgroup: The group owner of the file.
  3. Determine Your Current User and Groups:

    • Identify who you are currently logged in as and which groups you belong to.
      bash whoami id -Gn
    • Compare whoami output with the owner of the file, and id -Gn output with the group owner of the file. Are you the owner? Are you in the group?
  4. Assess Necessary Permissions:

    • To execute a script: You (or your group/others, depending on the setting) need x permission on the file itself.
    • To read a file: You need r permission on the file.
    • To write to a file: You need w permission on the file.
    • To list directory contents: You need r permission on the directory.
    • To change into/traverse a directory: You need x permission on the directory.
    • To create/delete files in a directory: You need w and x permissions on the directory.
  5. Apply the Fix (Using chmod and chown):

    • Changing Permissions (chmod): This is the most common fix. Use chmod to add the necessary permissions.

      • To make a script executable for the owner:
        bash chmod u+x /path/to/my_script.sh
      • To allow read/write for owner, read-only for group/others on a file:
        bash chmod 644 /path/to/config.txt
      • To allow read/write/execute for owner, read/execute for group/others on a directory (common for web content directories):
        bash chmod 755 /path/to/my_directory
      • To recursively apply permissions to files and directories within a directory: (Use with caution!)
        bash chmod -R 755 /path/to/directory # For directories chmod -R 644 /path/to/directory # For files only (after finding them with find)
      • Note: chmod can use symbolic (e.g., u+x) or octal (e.g., 755) modes. Octal mode combines read (4), write (2), and execute (1) values. 755 means:
        • Owner: 4+2+1 = 7 (rwx)
        • Group: 4+0+1 = 5 (r-x)
        • Others: 4+0+1 = 5 (r-x)
    • Changing Ownership (chown): If the file or directory is owned by the wrong user or group, you might need to change ownership. This typically requires sudo.

      • Change owner to ingrid for a file:
        bash sudo chown ingrid /path/to/some_file.txt
      • Change owner to ingrid and group to devgroup for a directory:
        bash sudo chown ingrid:devgroup /path/to/some_directory
      • Recursively change ownership for a directory and its contents: (Use with extreme caution!)
        bash sudo chown -R ingrid:devgroup /path/to/project_root
    • Adding User to a Group (usermod): If your user needs access because of group permissions, ensure you're in that group. This requires sudo and a re-login for changes to take effect.
      bash sudo usermod -aG devgroup ingrid # Then logout and log back in, or use 'newgrp devgroup' for immediate effect in current shell

    • Using sudo for Elevated Privileges: If you genuinely need to perform an action that requires root privileges (e.g., modifying system files), prepend your command with sudo. Always be judicious with sudo.
      bash sudo nano /etc/nginx/nginx.conf

  6. Advanced Checks (SELinux/AppArmor):

    • If standard permissions are correct, but you're still getting denied, check your security modules.
    • SELinux: Use sestatus to see if it's enabled. getenforce shows enforcing/permissive mode. audit.log often contains AVC denials (grep "AVC" /var/log/audit/audit.log). Temporarily set to permissive (sudo setenforce 0) to confirm if it's the issue (revert with sudo setenforce 1).
    • AppArmor: Use aa-status to check status. Review /var/log/syslog or dmesg for AppArmor denials.

Code Examples

Here are some concise, copy-paste ready examples for common permission scenarios:

1. Make a script executable:

# Verify current permissions (missing 'x' for user/group/others)
ls -l my_script.sh
# Output: -rw-r--r-- 1 user group 100 Jan 1 09:00 my_script.sh

# Add execute permission for the owner
chmod u+x my_script.sh

# Verify updated permissions
ls -l my_script.sh
# Output: -rwxr--r-- 1 user group 100 Jan 1 09:00 my_script.sh

2. Grant read/write access to a config file for the owner only:

# Secure a config file
chmod 600 production_config.ini

# Verify
ls -l production_config.ini
# Output: -rw------- 1 user group 250 Jan 1 09:05 production_config.ini

3. Set standard directory permissions (owner rwx, group rx, others rx):

# For a web root directory, for example
chmod 755 /var/www/html/mysite

# Verify
ls -ld /var/www/html/mysite
# Output: drwxr-xr-x 2 user group 4096 Jan 1 09:10 /var/www/html/mysite

4. Change file ownership to a specific user and group (requires sudo):

# Assume a file was created by root and needs to be owned by 'appuser' and 'appgroup'
sudo chown appuser:appgroup /opt/myapp/data/shared.txt

# Verify
ls -l /opt/myapp/data/shared.txt
# Output: -rw-r--r-- 1 appuser appgroup 1200 Jan 1 09:15 shared.txt

5. Add your user to an existing group (e.g., docker group) and verify (requires sudo and re-login):

# Add current user to the 'docker' group
sudo usermod -aG docker $(whoami)

# Log out and log back in, then verify group membership
id -Gn
# Output should now include 'docker'

Environment-Specific Notes

Permission issues can manifest differently or have unique considerations depending on your environment.

  • Cloud Instances (AWS EC2, GCP Compute Engine, Azure VMs):

    • Default Users: Often, cloud instances come with default users (e.g., ec2-user on Amazon Linux, ubuntu on Ubuntu AMIs, centos on CentOS images). These users typically have sudo privileges, but file ownership created by installation scripts (which often run as root) can cause issues.
    • SSH Key Permissions: Your SSH private key itself needs chmod 400 permissions. If not, ssh will deny access with a "Permission denied (publickey)" error. This isn't a filesystem permission on the remote server but on your local machine.
    • IAM Roles/Service Accounts: While not direct filesystem permissions, if a service running on a VM (e.g., an application trying to write to S3) experiences "Access Denied," it's often an IAM permission issue, not a local filesystem one.
    • Root Filesystem: I've seen situations where the root filesystem gets mounted read-only due to disk corruption or system health checks, leading to write errors across the board.
  • Docker Containers:

    • Inside the Container: Permissions are handled normally inside the container based on the container's user. By default, processes run as root inside the container unless specified by the USER directive in the Dockerfile.
    • Volume Mounts (-v): This is a frequent pain point. When you mount a host directory into a container, the host's permissions and ownership are retained. If the user inside the container doesn't have the necessary UID/GID to access the mounted directory from the host, you'll get "Permission denied". Often, aligning UIDs/GIDs or running the container as root (not recommended for production) or a specific user (docker run --user <UID>:<GID>) is necessary.
    • Docker Socket: Accessing the Docker daemon from within a container (Docker-in-Docker) or from your user requires your user to be in the docker group, which provides write access to /var/run/docker.sock.
  • Local Development Environments:

    • umask: Your shell's umask setting determines the default permissions for newly created files and directories. A restrictive umask (e.g., 077) can mean files you create aren't accessible to others by default, leading to issues in collaborative projects.
    • External Drives/NFS: External USB drives, network shares (NFS, SMB), or cloud sync folders often have their own permission nuances. noexec mounts can prevent execution, and ownership mapping can differ, leading to permission problems that aren't solvable with chmod/chown without remounting or adjusting server-side settings. I've often seen this when using shared development environments, where one user creates files and others can't modify them due to umask or misconfigured group access.

Frequently Asked Questions

  • Q: Why does sudo not always fix "Permission denied"?
    A: While sudo grants root privileges, it can't bypass all restrictions. Common reasons sudo might still fail include:

    1. Read-only filesystem: The underlying filesystem is mounted as read-only. sudo cannot change this.
    2. SELinux/AppArmor: These security modules can block even root-level access based on their policies.
    3. Immutable files: Files marked with the chattr +i attribute cannot be modified or deleted, even by root, without removing the attribute first (chattr -i).
  • Q: What is the difference between chmod 777 and chmod 755?
    A: chmod 777 grants read, write, and execute permissions to everyone (owner, group, and others). This is highly insecure for most files and directories and should be avoided unless absolutely necessary for very specific, non-sensitive temporary files. chmod 755 grants read, write, and execute to the owner, and read and execute to the group and others. This is a common and safer permission set for directories and executable scripts that need to be accessible (but not modifiable by) others.

  • Q: Can "Permission denied" happen for directories?
    A: Yes, absolutely. If you lack the x (execute) permission on a directory, you won't be able to cd into it or access its contents, resulting in "Permission denied." If you lack r (read) permission, you can't list its contents (ls). If you lack w (write) permission, you can't create or delete files within it.

  • Q: My script has execute permission but still fails with "Permission denied" when I run ./script.sh?
    A: Check two things:

    1. Shebang: Ensure the script has a correct "shebang" line at the very top (e.g., #!/bin/bash or #!/usr/bin/env python3). If this is missing or incorrect, the kernel doesn't know how to execute the file.
    2. Directory Permissions: Make sure the directory containing the script has execute (x) permission for your user, allowing you to traverse into it.