The chmod command controls who can read, write, and execute files on your Linux system. This is a critical skill whether you’re hardening SSH keys, deploying web applications, or managing team projects. A misconfigured permission can expose sensitive data or block legitimate users, so understanding how to read permission strings, apply numeric and symbolic modes, and avoid common pitfalls like chmod 777 saves both time and security headaches.
This guide shows you how to check existing permissions, apply changes using numeric and symbolic notation, handle recursive directory updates safely, work with special permission bits (setuid, setgid, sticky), and troubleshoot access problems in real environments ranging from shared web servers to SSH configurations.
How the chmod Command Controls Linux Permissions
If you are new to chmod, think of it as the permissions switchboard that tells Linux who can read, modify, or run your files. Updating those switches correctly keeps sensitive data private while giving teammates the access they need.
The chmod utility ships with every Linux distribution as part of GNU coreutils, so it is ready to use on bare nodes, container images, and desktop systems alike.
What Is the chmod Command?
chmod updates the mode bits attached to files and directories. Those bits describe the read, write, and execute permissions granted to the owner, the owning group, and everyone else. By adjusting the mode, you decide whether a script can run, a log file stays write-protected, or a shared folder inherits group access.
Why Use the chmod Command?
Every deployment workflow, from handing off backups to publishing web content, relies on correct permissions. chmod provides the quick adjustments you need: make a script executable, lock down SSH keys, or give a project group write access without exposing data to everyone on the system.
How chmod Command Syntax Works
Use the command in this form:
chmod [OPTIONS] MODE[,MODE]... FILE...
- chmod: The command that writes new permission bits to disk.
- [OPTIONS]: Flags such as
-Ror--reference=RFILEthat modify how the change is applied. - MODE[,MODE]…: The permissions you want to apply. Use numeric values like
755for full owner control, or symbolic changes such asu+xto add execute permission. - FILE…: One or more files or directories that will receive the updated mode.
At its simplest, run chmod 644 example.txt to give the owner read and write access while everyone else gets read-only access. Switch to symbolic mode when you want to adjust part of the mode. For example, chmod g+w shared.log lets your group update a shared log without touching owner or other permissions.
Use this quick reference to pick the right options for common permission tasks:
| Task | Options | What They Do |
|---|---|---|
| Copy permissions from a known-good file | --reference=RFILE | Applies the exact mode from the reference so related files stay aligned. |
| Change an entire project tree safely | -R | Recurses through directories; pair with symbolic modes like u=rwX,go=rX to avoid marking data files executable. |
| Reduce noise in automation scripts | -f / --quiet | Suppresses most error messages to keep CI logs focused on real issues. |
| Audit what changed during troubleshooting | -v / --changes | Prints a line for each file whose permissions were updated so you can confirm scope. |
| Protect the root directory during recursive runs | --preserve-root | Prevents accidental mode changes to / when using -R from an elevated shell. |
chmod offers both numeric and symbolic notation. Numeric mode replaces the entire permission set in one step, while symbolic mode lets you add, remove, or copy specific bits without touching the rest.
How Linux File Permissions Work with chmod
If you’re new to Linux permissions, think of them as a security gate that controls who can do what with your files. Every file and directory has three permission types (read, write, execute) assigned to three user categories (owner, group, others). Understanding how to view and modify these permissions is essential for managing file access securely.
Viewing Current Permissions
Before changing permissions, check what’s currently set using the ls -l command:
ls -l filename
This displays output like:
-rw-r--r-- 1 user group 1024 Oct 29 10:30 filename
Breaking down the permission string -rw-r--r--:
- First character (
-): File type (-for file,dfor directory,lfor symbolic link) - Characters 2-4 (
rw-): Owner permissions (read, write, no execute) - Characters 5-7 (
r--): Group permissions (read only) - Characters 8-10 (
r--): Others permissions (read only)
The Three Permission Types
Each position in the permission triplet represents a specific access level:
- r (read): View file contents or list directory contents
- w (write): Modify, delete, or rename the file; create or delete files in a directory
- x (execute): Run the file as a program; enter (cd into) a directory
Directories require execute permission to access their contents. Even if you have read permission, you cannot list files without execute permission.
Numeric and Symbolic Modes in chmod
chmod offers two methods for setting permissions: numeric (octal) mode and symbolic mode. Each serves different use cases. Numeric mode sets absolute permissions quickly, while symbolic mode adds or removes specific permissions without affecting others.
Use Numeric (Octal) Mode for Exact Permissions
Numeric mode uses a three-digit number where each digit represents permissions for owner, group, and others respectively. Each permission type has a binary value that translates to a decimal number:
- Read (r) = 4 (binary 100)
- Write (w) = 2 (binary 010)
- Execute (x) = 1 (binary 001)
- No permission = 0 (binary 000)
To calculate a permission digit, add the values of the permissions you want. For example:
- 7 = read + write + execute (4+2+1) = rwx
- 6 = read + write (4+2) = rw-
- 5 = read + execute (4+1) = r-x
- 4 = read only (4) = r–
- 3 = write + execute (2+1) = -wx
- 2 = write only (2) = -w-
- 1 = execute only (1) = –x
- 0 = no permissions (0) = —
When you use chmod 755, you’re setting three separate permission sets: 7 for the owner (rwx), 5 for the group (r-x), and 5 for others (r-x). This numeric shorthand replaces all existing permissions with the values you specify.
chmod 755 filename # Owner: rwx, Group: r-x, Others: r-x
Adjust Permissions with Symbolic Mode
Symbolic mode uses letters and operators to modify permissions without replacing the entire permission set. This method is more intuitive for making incremental changes.
Who (user classes):
- u = user (owner)
- g = group
- o = others
- a = all (equivalent to ugo)
What (operators):
- + = add permission
- – = remove permission
- = = set exact permission (removes others)
Which (permission types):
- r = read
- w = write
- x = execute
Symbolic mode lets you add execute permission to the owner without touching other permissions:
chmod u+x filename # Add execute for owner only
Use numeric mode when you want to set all permissions at once (chmod 644), and symbolic mode when you need to modify specific permissions (chmod g+w).
Common chmod Command Examples
With an understanding of how permissions and the chmod command work, let’s explore some practical examples.
Example 1: Changing Permissions Using Numeric Mode
chmod 755 filename
This command changes the permissions of ‘filename’ so that:
- The user (owner) has read (4), write (2), and execute (1) permissions – summed up to 7.
- The group and others have read (4) and execute (1) permissions, totaling 5.
In other words, the owner has full access, while the group members and others can read and execute the file but cannot modify it.
Example 2: Changing Permissions Using Symbolic Mode
chmod u+x filename
This command adds execute permission for the user to ‘filename’. Here’s the breakdown:
- u: Represents the user.
- +: Denotes that a permission is being added.
- x: Stands for execute permission.
To summarize, this command tells the system: “Add (+) execute (x) permission for the user (u) for this file (‘filename’)”.
Example 3: Removing Permissions
chmod go-w filename
This command removes write permissions for the group and others from ‘filename’:
- go: Stands for group and others.
- -: Signifies that a permission is being removed.
- w: Represents write permission.
This command removes the write permission from the group and other users, enhancing the file’s security.
Example 4: Setting All Permissions
chmod ugo+rwx filename
This command gives all permissions to all users for ‘filename’. The breakdown is as follows:
- ugo: Represents user, group, and others.
- +: Denotes that permissions are being added.
- rwx: Stands for read, write, and execute permissions.
This command effectively opens ‘filename’ to everyone. Use this with caution, considering the security implications of making files world-writable and executable.
Example 5: Using chmod with -R Option
chmod -R u=rwX,go=rX directoryname
This command recursively changes permissions across ‘directoryname’ and all nested content. The capital X adds execute permission only to directories and files that were already executable, preventing regular data files from accidentally becoming executable while ensuring directories remain traversable.
- -R: Applies the rule to the directory itself and everything under it.
- u=rwX: Gives the owner read/write access and only adds execute to directories or files that were already executable.
- go=rX: Gives group and others read access plus directory traversal without turning regular files into executables.
Use this safer pattern instead of a blanket chmod -R 755, which can unintentionally mark every file as executable.
Example 6: Changing Group Permissions
chmod g-wx filename
This command removes the write and execute permissions from the group for ‘filename’:
- g: Stands for the group.
- -: Indicates that permissions are being removed.
- wx: Represents write and execute permissions.
Group members associated with ‘filename’ will no longer be able to modify or execute it.
Example 7: Changing Multiple Permissions
chmod u=rwx,g=rx,o=r filename
This command sets different permissions for different types of users:
- u=rwx: Sets the user’s permissions to read, write, and execute.
- g=rx: Sets the group’s permissions to read and execute.
- o=r: Sets the other’s permissions to read only.
This allows you to control access levels for different types of users granularly.
Example 8: Copying Permissions
chmod --reference=filename1 filename2
This command copies the permissions from ‘filename1’ to ‘filename2’.
- –reference=filename1: Indicates that ‘filename1’ is the reference file from which permissions will be copied.
This command is convenient when you want to quickly apply the same permissions to multiple files.
Example 9: Changing Permissions Using Sticky Bit
chmod 1777 directoryname
This command sets the sticky bit (1) and applies 777 permissions to ‘directoryname’.
- The sticky bit (1) ensures that only the file owner, directory owner, or root user can delete or rename files inside the directory.
- 777: Gives everyone read, write, and execute access so users can create and manage their own files while the sticky bit prevents them from removing files they do not own.
This is the pattern used for shared writable directories such as /tmp, scratch areas, or upload folders where every user needs write access without the risk of deleting someone else’s work.
Example 10: Using chmod with Find Command
find /path -type f -exec chmod 644 {} \;
This command finds all regular files under /path and its subdirectories and changes their permissions to 644 (read/write for the owner, and read for group and others).
- find /path -type f: Finds all files under the given path.
- -exec chmod 644 {} \;: Changes the permissions of each file found.
This command is useful when you want to change the permissions of multiple files based on certain criteria. For more details on using find with -exec, see our comprehensive guide to the find -exec command.
Advanced chmod Command Examples
chmod has a few tricks that can make your life even easier. Let’s explore these advanced examples.
Advanced Example 1: Mirror Owner Permissions to the Group
chmod -R g=u /srv/team-project
Symbolic copies let you reuse existing permission sets instead of recalculating numeric values:
g=u: Copies the owner’s permissions to the group on each file, matching whatever read, write, or execute bits already exist.-R: Propagates the change through the project tree so nested files and directories inherit the mirrored bits.- Use this after migrating a personal workspace into a shared directory so teammates gain identical access without opening the content to other users.
Advanced Example 2: Setting Setuid, Setgid, and Sticky Bits
chmod 4755 /usr/bin/passwd
chmod 2775 /srv/team-project
chmod 1777 /srv/shared/tmp
These commands set the setuid, setgid, and sticky bits for a file or directory:
- The setuid bit (4): When set on a file, users can execute the file with the permissions of the file’s owner.
- The setgid bit (2): When set on a directory, new files and subdirectories inherit its group, which keeps collaborators aligned with the same group permissions.
- The sticky bit (1): Protects files inside a directory from being removed by other users. Combine it with setgid (for example,
chmod 3775 /srv/shared/tmp) when you need both shared group ownership and deletion protection; use plain1777for world-writable scratch spaces such as/tmp.
Advanced Example 3: Changing Permissions of Directories Only
find /path -type d -exec chmod 755 {} \;
This command changes the permissions of only the directories under a given path, leaving files as they are:
- find /path -type d: Finds all directories under the given path.
- -exec chmod 755 {} \;: Changes the permissions of each directory found.
This command is useful when you want to change the permissions of only the directories, not the files.
Advanced Example 4: Target Specific Files with find
find /srv/shared -type f -name "*.sh" -exec chmod 750 {} +
This pattern narrows recursive changes to the files that actually need new permissions:
-type fwith-name "*.sh": Matches only shell scripts while ignoring data files.-exec chmod 750 {} +: Batches files into a single chmod run, giving the owner full rights, the group execute access, and keeping the scripts private from other users.
Use this when you need to tighten permissions on executable files without disturbing the rest of the directory structure.
Advanced Example 5: Making a Script Executable by Everyone
chmod +x scriptname
This command adds the execute permission to the user, group, and others for ‘scriptname’:
- +x: Adds execute permission.
This is a common operation when you create a new script and want to make it executable.
Advanced Example 6: Using +X for Smarter Recursive Changes
chmod -R u+X,g+X /srv/shared
The capital +X operator adds execute permission only to directories and to files that already have at least one execute bit set. This keeps regular files from accidentally becoming executable while still allowing users to traverse directories.
-R: Applies the change recursively.u+X,g+X: Adds execute permission for the owner and group where appropriate.
Use +X when preparing shared directories. It preserves security by skipping non-executable files that should remain plain data.
Quick Reference: Common Permission Patterns
For quick reference, here are the most commonly used permission patterns organized by scenario:
Standard File and Directory Permissions
| Numeric | Symbolic | Meaning | Typical Use Case |
|---|---|---|---|
| 644 | rw-r–r– | Owner: read/write, Group/Others: read | Regular files, documents, web content (most common file permission) |
| 755 | rwxr-xr-x | Owner: full control, Group/Others: read/execute | Directories, scripts, executables (most common directory permission) |
| 600 | rw——- | Owner: read/write, Group/Others: none | Private files, SSH keys, passwords, sensitive config |
| 700 | rwx—— | Owner: full control, Group/Others: none | Private directories, ~/.ssh/, personal scripts |
| 444 | r–r–r– | Everyone: read only | Protected reference files, system docs you don’t want modified |
| 555 | r-xr-xr-x | Everyone: read/execute, no write | Protected executables, read-only shared directories |
Collaborative Team Permissions
| Numeric | Symbolic | Meaning | Typical Use Case |
|---|---|---|---|
| 664 | rw-rw-r– | Owner/Group: read/write, Others: read | Shared team files where group members can edit |
| 660 | rw-rw—- | Owner/Group: read/write, Others: none | Private team files, project data restricted to group |
| 775 | rwxrwxr-x | Owner/Group: full control, Others: read/execute | Shared team directories, collaborative projects |
| 770 | rwxrwx— | Owner/Group: full control, Others: none | Private team directories, restricted collaboration spaces |
| 2775 | rwxrwsr-x | Setgid: new files inherit group ownership | Shared project directories (ensures team members keep group access) |
Special Permissions and High-Risk Patterns
| Numeric | Symbolic | Meaning | Use Case / Security Warning |
|---|---|---|---|
| 4755 | rwsr-xr-x | Setuid: runs with owner privileges | System binaries like passwd, sudo. Use carefully; setuid grants escalated privileges. |
| 2755 | rwxr-sr-x | Setgid: runs with group privileges | Shared directories where new files inherit group ownership automatically. |
| 1777 | rwxrwxrwt | Sticky bit: only owner can delete own files | /tmp directory, public upload folders. Prevents users deleting others’ files. |
| 777 | rwxrwxrwx | Everyone: full control (dangerous!) | ⚠️ Avoid unless absolutely necessary. Major security risk; anyone can modify/delete. |
| 666 | rw-rw-rw- | Everyone: read/write | ⚠️ Rarely appropriate. Use only for temporary shared data files, never executables. |
When choosing permissions, start restrictive (600/700) and relax only as needed. It’s easier to grant access later than recover from a security breach caused by overly permissive settings.
Manage umask and Default Permissions
When Linux creates a new file or directory, it starts with broad default permissions (666 for files, 777 for directories) and then subtracts the current umask value. The result becomes the actual permission set. Knowing your umask explains why new files do not always inherit the permissions you expect.
To check the active umask for your shell session:
umask
The output is an octal value. For example, a umask of 0022 subtracts write permissions from group and others. New files appear as 644 (666 – 022) and new directories as 755 (777 – 022).
You can temporarily change the mask for your current shell:
# Restrictive default for private workstations
umask 0077
# Collaborative default where team members share a group
umask 0027
As a rule, use restrictive masks (like 077) when you want new files to be private by default. Use collaborative masks (like 027 or 002) when working in shared directories where group members need access. Remember that umask only affects future files; use chmod to adjust existing files if needed.
Real-World Permission Scenarios
Understanding permissions in context helps you apply chmod correctly in real situations. Here are common scenarios you’ll encounter.
Web Server Files and Directories
For Apache or Nginx web servers, proper permissions prevent security vulnerabilities while allowing the web server to function:
# Web root directories
chmod 755 /var/www/html
# Static files (HTML, CSS, JS, images)
find /var/www/html -type f -exec chmod 644 {} \;
# Directories
find /var/www/html -type d -exec chmod 755 {} \;
# Writable directories (uploads, cache)
chmod 775 /var/www/html/uploads
chmod 775 /var/www/html/cache
Never use 777 on web-accessible directories. You allow anyone to modify files, creating a serious security risk.
SSH Keys and Configuration
SSH is strict about key permissions and will refuse to work if they’re too permissive:
# SSH directory
chmod 700 ~/.ssh
# Private keys (critical - must be 600)
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
# Public keys
chmod 644 ~/.ssh/id_rsa.pub
# Authorized keys file
chmod 600 ~/.ssh/authorized_keys
# SSH config file
chmod 600 ~/.ssh/config
If your SSH keys have wrong permissions, you’ll get “permissions are too open” errors and SSH will refuse to use them.
Shared Project Directories
When multiple users work on the same project, use group permissions with the setgid bit:
# Set up shared project directory
chmod 2775 /shared/project
# This ensures:
# - Owner and group can read, write, execute
# - Others can read and execute
# - New files inherit the group (setgid bit)
# - Team members can collaborate effectively
Script Deployment
When deploying scripts to production, security matters:
# Production scripts (executable by owner only)
chmod 700 /usr/local/bin/backup-script.sh
# Scripts that need group execution (multiple admins)
chmod 750 /usr/local/bin/deploy-app.sh
# System-wide utilities (all users can execute)
chmod 755 /usr/local/bin/check-status.sh
User Home Directory Security
Protect user home directories from snooping:
# Home directory (owner can do everything, others can't access)
chmod 700 /home/username
# Personal files
chmod 600 ~/personal-notes.txt
chmod 600 ~/financial-data.csv
# Scripts you want to run
chmod 700 ~/bin/my-script.sh
Common Mistakes to Avoid
Even experienced Linux users sometimes make permission mistakes. Here are the most common pitfalls and how to avoid them.
The chmod 777 Trap
The most dangerous chmod mistake is using 777 to “fix” permission problems:
# WRONG - Never do this
chmod -R 777 /var/www/html
This makes every file world-writable, meaning any user (or compromised process) can modify, delete, or inject malicious code. Use 755 for directories and 644 for files instead. Only use 777 with the sticky bit (1777) for specific shared temp directories like /tmp:
# Correct pattern for shared scratch space
chmod 1777 /srv/shared/tmp
Recursive Permission Changes on System Directories
Never run recursive chmod on system directories:
# EXTREMELY DANGEROUS - Can break your entire system
chmod -R 755 /
chmod -R 644 /etc
This breaks system binaries, config files, and can make your system unbootable. Always target specific directories and double-check your path before using -R.
Confusing Ownership with Permissions
chmod changes permissions, but it doesn’t change ownership. If you get “permission denied” even after chmod, check ownership:
# Check who owns the file
ls -l filename
# If owned by wrong user, use chown (requires sudo)
sudo chown username:groupname filename
# Then set permissions
chmod 644 filename
Remember: chmod = permissions (read, write, execute), chown = ownership (who owns it).
Ignoring Execute Permission on Directories
Execute permission on directories means something different than on files. Without it, you can’t enter the directory or access files inside, even if they’re readable:
# WRONG - Directory without execute permission
chmod 644 /path/to/directory # Can't cd into it
# RIGHT - Directories need execute permission
chmod 755 /path/to/directory # Now you can access it
Symbolic Links and Permissions
chmod on a symbolic link changes the target file’s permissions, not the link itself. Symbolic links always show 777 permissions, but this is ignored:
# This changes the target file, not the link
chmod 644 symlink # Modifies the file symlink points to
To avoid changing the wrong file, always verify where a symlink points with ls -l before running chmod.
Forgetting About Special Permissions
When you set permissions numerically with three digits, you remove special bits (setuid, setgid, sticky):
# This removes the setgid bit if it was set
chmod 755 directory # Setgid bit is cleared
# To preserve setgid, use four digits
chmod 2755 directory # Explicitly sets setgid + 755
Troubleshooting Permission Issues
Permission problems are common in Linux. Here’s how to diagnose and fix them systematically.
Permission Denied Errors
When you see “Permission denied,” follow this troubleshooting sequence:
- Check current permissions and ownership:
ls -l /path/to/file
- Verify you’re the owner or in the right group:
whoami # Check your username
groups # Check your groups
id # See both username and groups
- Fix permissions or ownership as needed:
# If permissions are wrong
chmod 755 /path/to/file
# If ownership is wrong (requires sudo)
sudo chown youruser:yourgroup /path/to/file
Script Won’t Execute
If your script shows “Permission denied” when you try to run it:
# Check if execute permission is set
ls -l script.sh
# Add execute permission
chmod +x script.sh
# Or set specific permissions
chmod 755 script.sh
# Now run it
./script.sh
Can’t Access Directory Contents
If you can list a directory but can’t access files inside, the directory lacks execute permission:
# Check directory permissions
ls -ld /path/to/directory
# Add execute permission to directory
chmod +x /path/to/directory
# Or set full directory permissions
chmod 755 /path/to/directory
When to Use sudo for chmod Changes
If you’re not the owner, chmod requires sudo. However, using sudo changes files as root, which can create ownership issues:
# If you need to change permissions on files you don't own
sudo chmod 644 /etc/config-file
# But be careful - check if you should change ownership instead
sudo chown youruser:yourgroup /path/to/file
chmod 644 /path/to/file # Now you can chmod without sudo
SELinux and AppArmor Considerations
On systems with SELinux (RHEL, Fedora, Rocky Linux) or AppArmor (Ubuntu, Debian), file permissions are only part of access control. If chmod doesn’t fix your problem, check security contexts:
# Check SELinux context
ls -Z /path/to/file
# Check if SELinux is blocking access
sudo ausearch -m avc -ts recent
# Temporarily disable SELinux for testing (not recommended for production)
sudo setenforce 0
# Return to enforcing mode immediately after testing
sudo setenforce 1
If SELinux or AppArmor is blocking access, you need to adjust security policies in addition to file permissions. Always return SELinux to enforcing mode after tests and update the policy rather than leaving the system in a permissive state.
Extended ACLs and chmod
Modern Linux distributions support POSIX Access Control Lists (ACLs) for fine-grained permissions. If a file still behaves unexpectedly after chmod, check whether an ACL overrides the standard mode bits:
# View ACL entries
getfacl /path/to/file
# Grant a user read/write access without changing group ownership
setfacl -m u:alice:rw /path/to/file
# Remove ACL entries when they are no longer needed
setfacl -b /path/to/file
ACL entries work alongside chmod. Always review ACLs before assuming the numeric mode bits tell the whole story.
Conclusion
The chmod command is essential for managing file permissions in Linux. From basic permission changes to advanced techniques like recursive operations and special permission bits, mastering chmod helps you control access to files and directories effectively. The examples covered here should give you a solid foundation for handling permissions in real-world scenarios. Practice these commands in a test environment to build confidence, and always consider the security implications before making files world-readable or world-writable.