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
Or you try to edit a config file:
vim /etc/nginx/nginx.conf
# "E212: Can't open file for writing"
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)
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
-
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
Make a script executable for the owner:
chmod u+x script.sh
Give write permission to group:
chmod g+w config.yml
Removing Permissions
Remove write permission from owner:
chmod u-w filename
Remove read permission from group:
chmod g-r filename
Remove execute from others:
chmod o-x script.sh
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
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
Try to run it:
./deploy.sh
# Permission denied
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
Run it:
./deploy.sh
# Works!
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
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
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
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
Result: -rwx------
600 - Private file, not executable:
chmod 600 secrets.txt
# User: 6 (rw-) - read, write
# Group: 0 (---) - no access
# Others: 0 (---) - no access
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
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
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
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)
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/*
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)
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--
Common Mistakes
Mistake #1: Making everything 777
# NEVER do this
chmod 777 file.txt
# Everyone can read, write, execute - major security risk
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
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
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
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
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
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 {} \;
Checking Permissions
View permissions:
ls -l filename
stat filename # More detailed info
Test if you can read a file:
test -r filename && echo "Readable"
Test if you can write:
test -w filename && echo "Writable"
Test if you can execute:
test -x filename && echo "Executable"
Key Takeaways
- Three permissions: Read (4), Write (2), Execute (1)
- Three actors: User, Group, Others
-
Letter method is readable:
chmod u+x file -
Number method is faster:
chmod 755 file - Common patterns: 644 (files), 755 (scripts), 600 (private)
- Add permissions to calculate: 4+2+1=7 (rwx)
-
Always verify:
ls -lbefore and after changes - 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)