Quick Answer: Make executable:
chmod +x script.sh. Give owner full, group read, others nothing:chmod 750 file. Change owner:chown user:group file. Check permissions:ls -la.
Understanding Permissions
Every file has three permission groups:
-rwxrw-r-- 1 sam staff file.txt
│├──┤├─┤├─┤
│ │ │ │
│ │ │ └── Others (everyone else)
│ │ └───── Group (staff)
│ └───────── Owner (sam)
└──────────── File type (- = file, d = directory, l = link)
| Symbol | Permission | For Files | For Directories |
|---|---|---|---|
r |
Read | View contents | List files |
w |
Write | Modify contents | Create/delete files inside |
x |
Execute | Run as program | Enter directory (cd) |
- |
No permission | — | — |
Numeric (Octal) Mode
Each permission has a number. Add them up for each group:
| Permission | Number |
|---|---|
| Read (r) | 4 |
| Write (w) | 2 |
| Execute (x) | 1 |
| None (-) | 0 |
chmod 754 file
7 = Owner: r(4) + w(2) + x(1) = rwx
5 = Group: r(4) + w(0) + x(1) = r-x
4 = Others: r(4) + w(0) + x(0) = r--
Common Permission Numbers
| Number | Permissions | Typical Use |
|---|---|---|
777 |
rwxrwxrwx | Everyone full access (avoid this) |
755 |
rwxr-xr-x | Executables, public directories |
750 |
rwxr-x--- | Executables, private to group |
700 |
rwx------ | Private executables, ~/.ssh/ |
644 |
rw-r--r-- | Regular files, web content |
640 |
rw-r----- | Config files with group access |
600 |
rw------- | Private files, SSH keys |
400 |
r-------- | Read-only private files |
# Set permissions using numbers
chmod 755 script.sh
chmod 644 index.html
chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh/
Symbolic Mode
# Format: chmod [who][operator][permission] file
# Who: u=user/owner, g=group, o=others, a=all
# Operator: +=add, -=remove, ==set exactly
# Permission: r=read, w=write, x=execute
Examples
# Add execute for owner
chmod u+x script.sh
# Remove write from group and others
chmod go-w file.txt
# Set group to read-only
chmod g=r file.txt
# Add read+write for all
chmod a+rw file.txt
# Remove all permissions for others
chmod o= file.txt
# Make executable for everyone
chmod +x script.sh
# Set exact permissions (same as 755)
chmod u=rwx,g=rx,o=rx file
# Multiple changes at once
chmod u+x,g-w,o-rwx file
Recursive Permissions
# Apply to directory and all contents
chmod -R 755 /var/www/html/
# Apply to directories only
find /var/www -type d -exec chmod 755 {} +
# Apply to files only
find /var/www -type f -exec chmod 644 {} +
# Common web server setup
find /var/www -type d -exec chmod 755 {} + && find /var/www -type f -exec chmod 644 {} +
Ownership (chown)
# Change owner
chown sam file.txt
# Change owner and group
chown sam:staff file.txt
# Change group only
chown :staff file.txt
# or
chgrp staff file.txt
# Recursive
chown -R sam:www-data /var/www/html/
# Change ownership to match another file
chown --reference=other_file target_file
Special Permissions
Setuid (4xxx)
When set on an executable, it runs as the file's owner, not the user running it.
# Set setuid
chmod u+s file
chmod 4755 file
# Example: passwd command runs as root
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
# ^ the 's' means setuid is active
Setgid (2xxx)
On executables: runs as file's group. On directories: new files inherit the directory's group.
# Set setgid
chmod g+s directory/
chmod 2755 directory/
# Useful for shared directories
mkdir /shared
chown :devteam /shared
chmod 2775 /shared
# Now all files created inside belong to group 'devteam'
Sticky Bit (1xxx)
On directories: only file owners can delete their own files (used on /tmp).
# Set sticky bit
chmod +t directory/
chmod 1755 directory/
# Check: you'll see a 't' at the end
ls -la /tmp
# drwxrwxrwt ... /tmp
# ^ sticky bit
Checking Permissions
# List with permissions
ls -la
# Permissions in octal
stat -c "%a %n" *
# Just the permission string
stat -c "%A %n" *
# Detailed stat
stat file.txt
# Find files with specific permissions
find . -perm 777 # Exactly 777
find . -perm -644 # At least 644
find . -perm /u+x # Owner has execute
# Find files NOT owned by a specific user
find /var/www -not -user www-data
# Find world-writable files
find / -type f -perm -002 2>/dev/null
# Find setuid files
find / -perm -4000 2>/dev/null
Default Permissions (umask)
umask controls default permissions for new files and directories.
# View current umask
umask # e.g., 0022
# How it works:
# Files default: 666 - umask = permissions
# Dirs default: 777 - umask = permissions
# umask 022: files=644, dirs=755
# Set umask
umask 022 # Default (files: 644, dirs: 755)
umask 077 # Restrictive (files: 600, dirs: 700)
umask 002 # Group-friendly (files: 664, dirs: 775)
# Make permanent: add to ~/.bashrc
echo "umask 022" >> ~/.bashrc
Common Scenarios
Web Server
# Nginx/Apache web files
sudo chown -R www-data:www-data /var/www/html/
find /var/www/html -type d -exec chmod 755 {} +
find /var/www/html -type f -exec chmod 644 {} +
SSH
# SSH directory and keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config
Scripts
# Make script executable
chmod +x deploy.sh
# Only owner can run
chmod 700 admin-script.sh
Shared Directory
# Team members can read/write, others can't
mkdir /project
chown :devteam /project
chmod 2770 /project
# setgid ensures new files inherit group
Troubleshooting
| Problem | Fix |
|---|---|
Permission denied when running script |
chmod +x script.sh |
Permission denied accessing directory |
Need x on directory: chmod +x dir/ |
| SSH key rejected | chmod 600 ~/.ssh/id_ed25519 and chmod 700 ~/.ssh/ |
| Web server 403 Forbidden | chmod 755 on dirs, chmod 644 on files, check owner is www-data |
| Can't delete file in shared dir | Missing w on directory, or sticky bit is set |
Operation not permitted |
Need sudo or you're not the owner |
Quick Reference
| Command | What It Does |
|---|---|
chmod 755 file |
Owner:rwx, Group:r-x, Others:r-x |
chmod 644 file |
Owner:rw-, Group:r--, Others:r-- |
chmod 600 file |
Owner:rw-, private |
chmod +x file |
Add execute for all |
chmod u+x file |
Add execute for owner only |
chmod go-w file |
Remove write from group/others |
chmod -R 755 dir/ |
Recursive permissions |
chown user:group file |
Change ownership |
chown -R user:group dir/ |
Recursive ownership |
umask 022 |
Set default permission mask |
ls -la |
View permissions |
stat file |
Detailed file info |
Related Guides
- Linux File Permissions — detailed explanation
- chmod Guide — in-depth usage
- SSH Keys Setup — key permissions
- Server Hardening Guide — security checklist
- Bash Cheat Sheet — scripting
- Linux Commands Cheat Sheet — essential commands
Related Tools
- chmod Calculator — visual permission calculator