chmod Command in Linux with Examples

When working with files and directories in Linux, the chmod command lets you control who can read, write, and execute your files. Specifically, as an acronym for ‘Change Mode’, chmod adjusts file and directory permissions, which is a fundamental skill for anyone managing a Linux system. Additionally, whether you’re securing sensitive data or making a script executable, understanding chmod is essential for safe and effective file management.

Understanding the chmod Command in Linux

What Is the chmod Command?

The chmod command is a Linux command-line utility for modifying the file system mode. In practice, this mode determines the types of permissions that users and groups have over files and directories. Consequently, these permissions regulate who can read, write, and execute the specified files.

Why Use the chmod Command?

In Linux, files and directories are shared resources. Therefore, to protect these resources, you need to manage access permissions. The chmod command lets you control who can read, write, or execute files, which is critical for system security. Whether you’re a sysadmin protecting sensitive configuration files or a developer making scripts executable, chmod is a tool you’ll use constantly.

Understanding chmod Command Syntax

The chmod command follows the below syntax:

chmod [OPTIONS] MODE[,MODE]... FILE...

OPTIONS could be optional parameters providing additional functionality, MODE specifies the permissions to be set, and FILE is the file or directory whose permissions will be changed. In turn, chmod offers two primary methods for defining permissions: Numeric Mode and Symbolic Mode.

Different Options of the chmod Command

chmod Command Without Any Options

By default, without any options, chmod changes the permissions of the file to the mode specified by the user.

chmod 755 filename

The above command modifies the permissions of ‘filename’ so that the owner has read, write, and execute permissions (7), while the group and others have read and execute permissions (5).

chmod Command With Options

Several options can be used with chmod to extend its functionality:

  • -R or –recursive: Changes files and directories recursively.
  • -f or –silent or –quiet: Suppresses most error messages.
  • -v or –verbose: Outputs a diagnostic for every file processed.
  • –reference=RFILE: Sets permissions to match those of RFILE.

Understanding File Permissions with chmod

Permissions display as a ten-character string such as -rwxr-xr--, where the first character shows the file type and each three-character group records access for the owner, group, and others.

  • r (read): The permission to read the file’s contents.
  • w (write): The permission to modify or delete the file.
  • x (execute): The permission to execute the file.

For example, a file with rwx permissions for the user means that the user can read, write, and execute the file.

Numeric and Symbolic Modes in chmod

There are two ways to change permissions with chmod:

  • Numeric mode: Uses numbers to represent permissions. Read is 4, write is 2, and execute is 1. Add these numbers together to set permissions. For example, to give the user read, write, and execute permissions (4+2+1=7), you would use:
chmod 700 filename
  • Symbolic mode: Uses letters to represent users (u for user, g for group, o for others) and permissions (r, w, x). For example, to add execute permission for the user:
chmod u+x filename

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’. In detail:

  • go: Stands for group and others.
  • -: Signifies that a permission is being removed.
  • w: Represents write permission.

Therefore, 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:

Advertisement
  • ugo: Represents user, group, and others.
  • +: Denotes that permissions are being added.
  • rwx: Stands for read, write, and execute permissions.

As a result, 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 the permissions of all files and directories in ‘directoryname’ while keeping plain files from becoming executable.

  • -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

As a result, this command removes the write and execute permissions from the group for ‘filename’. Here’s the explanation:

  • g: Stands for the group.
  • -: Indicates that permissions are being removed.
  • wx: Represents write and execute permissions.

As a result, 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

In turn, this command sets different permissions for different types of users. Here’s what it does:

  • 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.

Similarly, 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

In this case, the 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.

Consequently, 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 {} \;

Afterward, 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

As with any Linux command, chmod has a few tricks that can make your life even easier. With that in mind, 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 plain 1777 for world-writable scratch spaces such as /tmp.

Advanced Example 3: Changing Permissions of Directories Only

find /path -type d -exec chmod 755 {} \;

In contrast, 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.

As a result, 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 {} +

Consequently, this pattern narrows recursive changes to the files that actually need new permissions:

Advertisement
  • -type f with -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.

Accordingly, 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.

Likewise, 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.

Therefore, use +X when preparing shared directories. It preserves security by skipping non-executable files that should remain plain data.

Checking Current Permissions

Before changing permissions, you need to see what’s currently set. Specifically, the ls -l command displays detailed file information including permissions.

ls -l filename

For example, this outputs something like:

-rw-r--r-- 1 user group 1024 Oct 29 10:30 filename

Specifically, breaking down the permission string -rw-r--r--:

  • First character (-): File type (- for file, d for directory, l for 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)

For directories, use ls -ld to see the directory’s own permissions rather than its contents:

ls -ld /path/to/directory

To display permissions in numeric form, use stat:

stat -c "%a %n" filename

This prints the mode as an octal value (such as 644) alongside the file name, which is handy when you want to compare against chmod commands.

Quick Reference: Common Permission Patterns

For quick reference, here are the most commonly used permission patterns and their typical use cases:

NumericSymbolicMeaningCommon Use Case
644rw-r–r–Owner: read/write, Group/Others: read onlyRegular files, text documents, web content
755rwxr-xr-xOwner: read/write/execute, Group/Others: read/executeDirectories, executables, scripts
700rwx——Owner: read/write/execute, Group/Others: no accessPrivate directories, SSH directories
600rw——-Owner: read/write, Group/Others: no accessPrivate files, SSH keys, config files
664rw-rw-r–Owner/Group: read/write, Others: readShared team files
775rwxrwxr-xOwner/Group: read/write/execute, Others: read/executeShared team directories
777rwxrwxrwxEveryone: read/write/execute (use sparingly)Avoid! Security risk except for sticky directories like /tmp
4755rwsr-xr-xSetuid bit with owner read/write/execute, Group/Others: read/executeSpecial executables (use carefully)
2755rwxr-sr-xSetgid bit with owner/group read/write/execute, Others: read/executeShared group directories
1777rwxrwxrwtSticky bit with everyone read/write/execute, deletions restricted by sticky bit/tmp directory, shared writable directories

Understanding 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. Consequently, 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 therefore appear as 644 (666 – 022) and new directories as 755 (777 – 022).

Alternatively, 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. Accordingly, here are common scenarios you’ll encounter.

Web Server Files and Directories

For instance, for Apache or Nginx web servers, proper permissions prevent security vulnerabilities while allowing the web server to function:

Advertisement
# 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. Otherwise, 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

Otherwise, 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

Likewise, 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:

Advertisement
  1. Check current permissions and ownership:
ls -l /path/to/file
  1. Verify you’re the owner or in the right group:
whoami        # Check your username
groups        # Check your groups
id            # See both username and groups
  1. 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

Understanding sudo and Permissions

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

If SELinux or AppArmor is blocking access, you need to adjust security policies in addition to file permissions. This is beyond chmod’s scope but important to know when troubleshooting.

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.

Leave a Comment