DEV Community

Cover image for Linux File Permissions
NJEI
NJEI

Posted on

Linux File Permissions

Linux File Permissions Demystified: Understanding rwx and chmod

The Problem: Access Denied

You created a script. You try to run it: ./deploy.sh

bash: ./deploy.sh: Permission denied
Enter fullscreen mode Exit fullscreen mode

Or you try to edit a config file:

vim /etc/nginx/nginx.conf
# "E212: Can't open file for writing"
Enter fullscreen mode Exit fullscreen mode

This is Linux permissions in action. Understanding how they work isn't optional—it's essential for managing servers, deploying code, and troubleshooting access issues.

The Three Permissions: Read, Write, Execute

Every file and directory has three types of permissions:

  • Read (r) - View file contents or list directory contents
  • Write (w) - Modify file or create/delete files in directory
  • Execute (x) - Run file as program or enter directory

The Three Actors: User, Group, Others

Permissions apply to three categories of people:

  • User (u) - The file owner (whoever created it)
  • Group (g) - Users in the file's group
  • Others (o) - Everyone else on the system

When you run ls -l, you see these permissions:

-rwxr-xr--  1 ubuntu developers  156 Dec 08 10:00 script.sh
 ││││││││
 │││││││└─ Others: r-- (read only)
 ││││││└── Group: r-x (read and execute)
 │││││└─── User: rwx (read, write, execute)
 ││││└──── File type: - (regular file)
Enter fullscreen mode Exit fullscreen mode

Breaking it down:

  • User (owner): rwx - Can read, write, and execute
  • Group: r-x - Can read and execute (not write)
  • Others: r-- - Can only read

Method 1: Using Letters with chmod

The chmod command changes permissions. The letter method is intuitive and readable.

Basic Syntax

chmod [who][operation][permission] filename
Enter fullscreen mode Exit fullscreen mode
  • Who: u (user), g (group), o (others), a (all)
  • Operation: + (add), - (remove), = (set exactly)
  • Permission: r (read), w (write), x (execute)

Adding Permissions

Give read permission to everyone:

chmod ugo+r file.txt
# Or shorter:
chmod a+r file.txt
Enter fullscreen mode Exit fullscreen mode

Make a script executable for the owner:

chmod u+x script.sh
Enter fullscreen mode Exit fullscreen mode

Give write permission to group:

chmod g+w config.yml
Enter fullscreen mode Exit fullscreen mode

Removing Permissions

Remove write permission from owner:

chmod u-w filename
Enter fullscreen mode Exit fullscreen mode

Remove read permission from group:

chmod g-r filename
Enter fullscreen mode Exit fullscreen mode

Remove execute from others:

chmod o-x script.sh
Enter fullscreen mode Exit fullscreen mode

Setting Exact Permissions

Set permissions explicitly (replaces existing):

chmod u=rwx,g=rx,o=r file.txt
# User: read, write, execute
# Group: read, execute
# Others: read only
Enter fullscreen mode Exit fullscreen mode

Real-World Example: Making a Script Executable

You download a deployment script:

ls -l deploy.sh
-rw-r--r--  1 ubuntu ubuntu  256 Dec 08 10:00 deploy.sh
Enter fullscreen mode Exit fullscreen mode

Try to run it:

./deploy.sh
# Permission denied
Enter fullscreen mode Exit fullscreen mode

The file isn't executable. Fix it:

chmod u+x deploy.sh

ls -l deploy.sh
-rwxr--r--  1 ubuntu ubuntu  256 Dec 08 10:00 deploy.sh
# Now it has x for user
Enter fullscreen mode Exit fullscreen mode

Run it:

./deploy.sh
# Works!
Enter fullscreen mode Exit fullscreen mode

Method 2: Using Numbers with chmod

Numbers are faster to type and commonly used in documentation. They might look cryptic, but they follow a logical pattern.

The Three-Digit System

chmod 755 file.txt
       │││
       ││└─ Others permissions
       │└── Group permissions
       └─── User permissions
Enter fullscreen mode Exit fullscreen mode

Each digit represents permissions for one actor:

  • First digit: User (owner)
  • Second digit: Group
  • Third digit: Others

How to Calculate the Numbers

Each permission has a value:

  • Read (r) = 4
  • Write (w) = 2
  • Execute (x) = 1

Add them together to get the digit for each actor:

Number Calculation Permissions Meaning
0 0 --- No permissions
1 1 --x Execute only
2 2 -w- Write only
3 2+1 -wx Write and execute
4 4 r-- Read only
5 4+1 r-x Read and execute
6 4+2 rw- Read and write
7 4+2+1 rwx Read, write, and execute

Common Permission Patterns

755 - Standard for executable files:

chmod 755 script.sh
# User: 7 (rwx) - read, write, execute
# Group: 5 (r-x) - read, execute
# Others: 5 (r-x) - read, execute
Enter fullscreen mode Exit fullscreen mode

Result: -rwxr-xr-x

644 - Standard for regular files:

chmod 644 document.txt
# User: 6 (rw-) - read, write
# Group: 4 (r--) - read only
# Others: 4 (r--) - read only
Enter fullscreen mode Exit fullscreen mode

Result: -rw-r--r--

700 - Private file, owner only:

chmod 700 private-key.pem
# User: 7 (rwx) - read, write, execute
# Group: 0 (---) - no access
# Others: 0 (---) - no access
Enter fullscreen mode Exit fullscreen mode

Result: -rwx------

600 - Private file, not executable:

chmod 600 secrets.txt
# User: 6 (rw-) - read, write
# Group: 0 (---) - no access
# Others: 0 (---) - no access
Enter fullscreen mode Exit fullscreen mode

Result: -rw-------

444 - Read-only for everyone:

chmod 444 readonly.txt
# User: 4 (r--) - read only
# Group: 4 (r--) - read only
# Others: 4 (r--) - read only
Enter fullscreen mode Exit fullscreen mode

Result: -r--r--r--

Converting Between Letters and Numbers

Let's say you see: -rwxr-xr--

Convert to numbers:

  • User: rwx = 4+2+1 = 7
  • Group: r-x = 4+0+1 = 5
  • Others: r-- = 4+0+0 = 4

Result: 754

Or going the other way, chmod 640 file.txt:

  • User: 6 = 4+2 = rw-
  • Group: 4 = 4 = r--
  • Others: 0 = 0 = ---

Result: -rw-r-----

Real-World Scenarios

Scenario 1: Securing SSH Keys

SSH keys must have strict permissions or SSH refuses to use them:

ls -l ~/.ssh/id_rsa
-rw-rw-r-- 1 ubuntu ubuntu 1679 Dec 08 10:00 /home/ubuntu/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

SSH will reject this (too open). Fix it:

chmod 600 ~/.ssh/id_rsa

ls -l ~/.ssh/id_rsa
-rw------- 1 ubuntu ubuntu 1679 Dec 08 10:00 /home/ubuntu/.ssh/id_rsa
# Now SSH accepts it
Enter fullscreen mode Exit fullscreen mode

Scenario 2: Web Server Files

You're setting up a website. Files need to be readable by the web server but not writable:

# HTML/CSS/JS files
chmod 644 *.html *.css *.js
# Result: -rw-r--r-- (owner can edit, everyone can read)

# Upload directory needs write access
chmod 755 uploads/
# Result: drwxr-xr-x (owner can write, everyone can read/enter)
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Shared Team Directory

Your team needs to collaborate on files:

# Create shared directory
mkdir /shared/project

# Set permissions: owner full access, group can read/write
chmod 770 /shared/project
# Result: drwxrwx--- (owner and group full access, others none)

# Files created inside inherit group access
chmod g+w /shared/project/*
Enter fullscreen mode Exit fullscreen mode

Scenario 4: Protecting Configuration Files

Config files often contain sensitive data:

# Database config
chmod 640 database.conf
# Result: -rw-r----- (owner can edit, group can read, others nothing)

# Even more restrictive
chmod 600 secrets.env
# Result: -rw------- (only owner can access)
Enter fullscreen mode Exit fullscreen mode

Combining Both Methods

You can use letters and numbers together in your workflow:

# Set base permissions with numbers (fast)
chmod 644 file.txt

# Add execute for user with letters (clear intent)
chmod u+x file.txt

# Result: -rwxr--r--
Enter fullscreen mode Exit fullscreen mode

Common Mistakes

Mistake #1: Making everything 777

# NEVER do this
chmod 777 file.txt
# Everyone can read, write, execute - major security risk
Enter fullscreen mode Exit fullscreen mode

Only use 777 in very specific debugging scenarios, and remove it immediately after.

Mistake #2: Forgetting the leading 0 for octal

In scripts, you might see:

chmod 0755 script.sh
Enter fullscreen mode Exit fullscreen mode

The leading 0 indicates octal notation. Both work, but 0755 is more explicit.

Mistake #3: Wrong permissions on SSH directories

SSH is picky:

# SSH directory structure
chmod 700 ~/.ssh/              # Directory
chmod 600 ~/.ssh/id_rsa        # Private key
chmod 644 ~/.ssh/id_rsa.pub    # Public key
chmod 644 ~/.ssh/authorized_keys  # Authorized keys
Enter fullscreen mode Exit fullscreen mode

Mistake #4: Not checking current permissions first

Always check before changing:

ls -l filename  # Check current permissions
chmod 644 filename  # Then change
ls -l filename  # Verify the change
Enter fullscreen mode Exit fullscreen mode

Quick Reference

Letter Method Cheat Sheet

chmod u+x file     # Add execute for user
chmod g-w file     # Remove write from group
chmod o+r file     # Add read for others
chmod a+x file     # Add execute for all
chmod u=rwx file   # Set user to rwx exactly
chmod go-rwx file  # Remove all permissions from group and others
Enter fullscreen mode Exit fullscreen mode

Number Method Cheat Sheet

Permission Number Letter Use Case
rwxrwxrwx 777 - Avoid (security risk)
rwxr-xr-x 755 Scripts Executable files
rwxr-x--- 750 - Group executable
rwx------ 700 - Private executable
rw-rw-rw- 666 - Avoid (security risk)
rw-rw-r-- 664 - Shared editable file
rw-r--r-- 644 Documents Standard files
rw-r----- 640 Configs Readable by group
rw------- 600 Keys Private files
r--r--r-- 444 - Read-only for all

Advanced: Recursive Permissions

Change permissions for all files in a directory:

# Change all files and subdirectories
chmod -R 755 /var/www/html/

# Be careful with -R - it affects everything below
Enter fullscreen mode Exit fullscreen mode

Better approach - set different permissions for files vs directories:

# Directories: 755 (rwxr-xr-x)
find /var/www/html -type d -exec chmod 755 {} \;

# Files: 644 (rw-r--r--)
find /var/www/html -type f -exec chmod 644 {} \;
Enter fullscreen mode Exit fullscreen mode

Checking Permissions

View permissions:

ls -l filename
stat filename  # More detailed info
Enter fullscreen mode Exit fullscreen mode

Test if you can read a file:

test -r filename && echo "Readable"
Enter fullscreen mode Exit fullscreen mode

Test if you can write:

test -w filename && echo "Writable"
Enter fullscreen mode Exit fullscreen mode

Test if you can execute:

test -x filename && echo "Executable"
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. Three permissions: Read (4), Write (2), Execute (1)
  2. Three actors: User, Group, Others
  3. Letter method is readable: chmod u+x file
  4. Number method is faster: chmod 755 file
  5. Common patterns: 644 (files), 755 (scripts), 600 (private)
  6. Add permissions to calculate: 4+2+1=7 (rwx)
  7. Always verify: ls -l before and after changes
  8. Never use 777: Major security risk

Understanding permissions is fundamental to Linux. Whether you prefer letters (readable) or numbers (fast), both methods give you precise control over who can access your files.


What permission pattern do you use most? Share your use cases in the comments.

Top comments (0)