ToolPal

Linux File Permissions and chmod Command β€” Complete Guide

Linux File Permissions and chmod Command β€” Complete Guide

Master Linux file permissions with this comprehensive chmod guide. Learn octal notation, symbolic mode, and common permission patterns with examples.

March 22, 202614 min read

Introduction

Every file and directory on a Linux system has a set of permissions that determines who can read, write, or execute it. Understanding these permissions is fundamental to working with Linux, whether you are managing a web server, deploying applications, or simply organizing files on your development machine.

The chmod command is the primary tool for modifying these permissions. Despite its apparent simplicity, chmod has enough depth that even experienced developers occasionally reach for a reference. This guide covers everything you need to know about Linux file permissions and the chmod command, from basic concepts to advanced special permissions.

Understanding Linux File Permissions

Linux file permissions are built around three types of access and three categories of users.

The Three Permission Types

  • Read (r): View the contents of a file, or list the contents of a directory.
  • Write (w): Modify or delete a file, or add and remove files within a directory.
  • Execute (x): Run a file as a program or script, or enter a directory with cd.

The Three User Categories

  • Owner (u): The user who owns the file. By default, this is the user who created it.
  • Group (g): The group assigned to the file. All users in this group share the group permissions.
  • Others (o): Everyone else on the system who is not the owner and not in the file's group.

Every file on a Linux system has exactly one owner, belongs to exactly one group, and has a defined set of permissions for each of these three categories.

How to Read Permission Strings

When you run ls -l in a terminal, you see output like this:

ls -l
-rwxr-xr-- 1 alice developers 4096 Mar 22 10:30 deploy.sh
drwxr-x--- 2 alice developers 4096 Mar 22 10:30 config/

The first column is the permission string. It is ten characters long and breaks down as follows:

d rwx r-x r--
|  |   |   |
|  |   |   +-- Others permissions (read only)
|  |   +------ Group permissions (read + execute)
|  +---------- Owner permissions (read + write + execute)
+------------- File type (d = directory, - = regular file, l = symlink)

Each position is either the permission letter or a dash (-) indicating that permission is not granted. Here are several examples:

Permission StringMeaning
-rw-r--r--Owner can read/write. Group and others can only read.
-rwxr-xr-xOwner has full access. Group and others can read and execute.
drwx------Directory. Only the owner can read, write, and enter it.
-rw-------Only the owner can read and write. No access for anyone else.
-rwxrwxrwxFull access for everyone. Generally a security risk.

Octal (Numeric) Notation

Octal notation represents permissions as a three-digit number, where each digit corresponds to the owner, group, and others respectively. Each digit is the sum of permission values:

ValuePermission
4Read (r)
2Write (w)
1Execute (x)
0No permission

You add these values together for each user category. For example:

  • 7 = 4 + 2 + 1 = read + write + execute (rwx)
  • 6 = 4 + 2 = read + write (rw-)
  • 5 = 4 + 1 = read + execute (r-x)
  • 4 = 4 = read only (r--)
  • 0 = no permissions (---)

So when you see chmod 755, it means:

7 = rwx (owner: read + write + execute)
5 = r-x (group: read + execute)
5 = r-x (others: read + execute)

Here is a quick reference for all possible digit values:

0 = ---   (no permissions)
1 = --x   (execute only)
2 = -w-   (write only)
3 = -wx   (write + execute)
4 = r--   (read only)
5 = r-x   (read + execute)
6 = rw-   (read + write)
7 = rwx   (read + write + execute)

If you need to quickly convert between permission strings and octal values, use our chmod Calculator for instant results.

Symbolic Notation

Symbolic notation uses letters and operators to modify permissions. It is often more intuitive for making targeted changes because you do not need to specify the entire permission set.

The Syntax

chmod [who][operator][permission] file

Who:

  • u -- owner (user)
  • g -- group
  • o -- others
  • a -- all (owner + group + others)

Operator:

  • + -- add permission
  • - -- remove permission
  • = -- set exact permission

Permission:

  • r -- read
  • w -- write
  • x -- execute

Symbolic Mode Examples

# Add execute permission for the owner
chmod u+x script.sh

# Remove write permission from group and others
chmod go-w config.yml

# Set read-only for everyone
chmod a=r readme.txt

# Add read and execute for group
chmod g+rx shared-tool

# Remove all permissions for others
chmod o= private.key

# Add execute for everyone, remove write for others
chmod a+x,o-w deploy.sh

# Set owner to rwx, group to rx, others to nothing
chmod u=rwx,g=rx,o= project-dir

Symbolic notation is particularly useful when you only want to change one aspect of the permissions without affecting the rest. For instance, chmod u+x script.sh adds execute permission for the owner without touching any other permissions.

Common chmod Patterns

Certain permission patterns appear repeatedly in real-world Linux administration. Here are the most important ones and when to use them.

644 -- Standard Files

chmod 644 index.html
# Owner: read + write | Group: read | Others: read

This is the default for most regular files. The owner can edit the file, and everyone else can read it. Use this for HTML files, configuration files that are not sensitive, and general documents.

755 -- Executable Files and Directories

chmod 755 deploy.sh
chmod 755 /var/www/html
# Owner: full access | Group: read + execute | Others: read + execute

The standard permission for scripts, binaries, and directories that need to be accessible. The owner has full control, while others can read and execute (or traverse, in the case of directories) but cannot modify.

700 -- Private Directories

chmod 700 ~/.ssh
# Owner: full access | Group: none | Others: none

Only the owner can access the file or directory. Essential for sensitive directories like ~/.ssh or private configuration directories.

600 -- Private Files

chmod 600 ~/.ssh/id_rsa
chmod 600 .env
# Owner: read + write | Group: none | Others: none

Only the owner can read and write the file. No one else has any access. Required for SSH private keys, environment files with secrets, and any file containing credentials.

444 -- Read-Only for Everyone

chmod 444 LICENSE
# Owner: read | Group: read | Others: read

No one can modify the file, including the owner (without changing permissions first). Useful for files that should never be accidentally edited, like license files or locked configuration.

777 -- Full Access for Everyone

chmod 777 /tmp/shared-workspace
# Owner: full | Group: full | Others: full

Every user can read, write, and execute. Avoid this in production. It is a significant security risk because any user or process on the system can modify or delete the file. Only use it in isolated development or temporary debugging scenarios.

Quick Reference Table

OctalStringTypical Use
644-rw-r--r--Regular files (HTML, CSS, images)
755-rwxr-xr-xScripts, binaries, web directories
700-rwx------Private directories (~/.ssh)
600-rw-------Private keys, .env files, credentials
444-r--r--r--Read-only files, licenses
664-rw-rw-r--Group-collaborative files
775-rwxrwxr-xGroup-collaborative directories
777-rwxrwxrwxAvoid in production

chmod Command Syntax and Options

The full syntax of chmod is:

chmod [options] mode file...

Key Options

# Apply permissions recursively to directories and their contents
chmod -R 755 /var/www/html

# Show verbose output for each file changed
chmod -v 644 *.html

# Show output only when a change is made
chmod -c u+x scripts/*.sh

# Suppress error messages
chmod -f 600 missing-file

# Use a reference file to copy its permissions
chmod --reference=source.conf target.conf

Practical Examples

# Make a script executable
chmod +x backup.sh

# Secure an SSH directory and its contents
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys

# Set web server file permissions
chmod -R 644 /var/www/html/*.html
chmod -R 755 /var/www/html/cgi-bin/

# Restrict a configuration file
chmod 600 /etc/myapp/database.yml

# Make all shell scripts in a directory executable
chmod u+x scripts/*.sh

# Remove write access from a production config
chmod a-w /etc/nginx/nginx.conf

Combining with find for Granular Control

A common pattern is to set different permissions for files and directories within the same tree:

# Set directories to 755 and files to 644 recursively
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;

# Make only shell scripts executable
find /opt/scripts -name "*.sh" -exec chmod u+x {} \;

# Remove world-readable permissions from all config files
find /etc/myapp -type f -exec chmod o-r {} \;

This approach is more precise than chmod -R because it lets you differentiate between files and directories, which often require different permission sets.

Special Permissions

Beyond the standard read, write, and execute bits, Linux supports three special permission types. These are represented as a fourth octal digit prepended to the standard three.

Setuid (4)

When set on an executable, the file runs with the permissions of the file's owner rather than the user executing it.

chmod 4755 /usr/bin/special-tool
chmod u+s /usr/bin/special-tool

The classic example is the passwd command. It needs to modify /etc/shadow, which is owned by root. The setuid bit allows any user to run passwd with root-level file access for that specific purpose.

In ls -l output, a setuid file shows an s in place of the owner's execute bit:

-rwsr-xr-x 1 root root 63960 Feb 10 12:00 /usr/bin/passwd

Setgid (2)

When applied to a directory, new files created within it inherit the directory's group rather than the creating user's primary group. On executables, it works like setuid but for group membership.

chmod 2775 /opt/team-project
chmod g+s /opt/team-project

This is invaluable for shared project directories. Without setgid, every file a team member creates would belong to their personal group, making collaboration difficult.

drwxrwsr-x 2 root developers 4096 Mar 22 10:30 /opt/team-project

Notice the s in the group execute position.

Sticky Bit (1)

When set on a directory, only the file's owner (or root) can delete or rename files within it, even if other users have write access to the directory.

chmod 1777 /tmp
chmod +t /tmp

The /tmp directory is the most common example. Everyone can create files in /tmp, but users cannot delete each other's files. In ls -l output, the sticky bit appears as a t in the others' execute position:

drwxrwxrwt 15 root root 4096 Mar 22 10:30 /tmp

Special Permissions Summary

PermissionOctalSymbolEffect on FileEffect on Directory
Setuid4000u+sRuns as file ownerNo standard effect
Setgid2000g+sRuns as file groupNew files inherit group
Sticky Bit1000+tNo standard effectOnly owner can delete files

Best Practices for Security

Following a few principles will keep your systems secure while remaining practical for day-to-day work.

Apply the Principle of Least Privilege

Grant only the minimum permissions required for a task. If a file only needs to be read, do not make it writable. If a script only needs to be run by the owner, do not grant execute to the group or others.

# Good: minimal permissions
chmod 600 .env
chmod 700 ~/.ssh

# Bad: overly permissive
chmod 777 .env
chmod 755 ~/.ssh

Never Use 777 in Production

There is almost never a legitimate reason to use chmod 777 on a production system. If something seems to require it, the underlying issue is usually a misconfigured user, group, or ownership rather than a permissions problem. Use chown or chgrp to fix ownership before loosening permissions.

Secure Sensitive Files Immediately

SSH keys, API tokens, environment files, and database credentials should always be 600 or 640 at most. Many tools, including OpenSSH, will refuse to work if key files have overly permissive settings.

chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
chmod 600 .env
chmod 600 /etc/myapp/secrets.yml

Use Groups for Collaboration

Instead of widening permissions for "others," create a dedicated group, add the relevant users, and use group permissions. Combine this with the setgid bit on shared directories so new files automatically inherit the correct group.

# Create a shared directory with proper group permissions
sudo groupadd webteam
sudo usermod -aG webteam alice
sudo usermod -aG webteam bob
sudo mkdir /var/www/project
sudo chown root:webteam /var/www/project
sudo chmod 2775 /var/www/project

Audit Permissions Regularly

On production servers, periodically check for files with dangerous permissions:

# Find all world-writable files
find / -type f -perm -o+w 2>/dev/null

# Find all setuid files (potential privilege escalation vectors)
find / -type f -perm -4000 2>/dev/null

# Find files with no owner (orphaned files)
find / -nouser -o -nogroup 2>/dev/null

Set a Secure umask

The umask defines the default permissions for newly created files and directories. A umask of 022 results in files with 644 and directories with 755. A more restrictive umask of 027 gives files 640 and directories 750, preventing "others" from accessing new files by default.

# Check current umask
umask

# Set a restrictive umask for the session
umask 027

# Make it permanent by adding to ~/.bashrc or ~/.zshrc
echo "umask 027" >> ~/.bashrc

chmod vs. chown vs. chgrp

These three commands are related but serve distinct purposes:

CommandPurposeExample
chmodChange file permissionschmod 755 script.sh
chownChange file owner (and optionally group)chown alice:devs file.txt
chgrpChange file groupchgrp webteam index.html

When troubleshooting access issues, start by checking both ownership (ls -l) and permissions. Often the fix is changing ownership with chown rather than loosening permissions with chmod.

Using the chmod Calculator

Manually converting between symbolic and octal notation is straightforward once you have practiced, but it can be tedious when you are setting up a new server or reviewing complex permission sets. Use our chmod Calculator to visually toggle permissions and instantly see the corresponding octal value, symbolic notation, and the resulting chmod command. It is especially useful for verifying special permissions like setuid, setgid, and the sticky bit.

Conclusion

Linux file permissions are one of the foundational pillars of system security. The chmod command gives you precise control over who can access, modify, and execute every file and directory on your system. By understanding octal and symbolic notation, applying the principle of least privilege, and using groups effectively, you can maintain a secure environment without sacrificing usability.

Remember the key rules: keep sensitive files restricted to 600 or 700, use 755 for executables and public directories, avoid 777 entirely in production, and audit your permissions regularly. With these practices in place, your Linux systems will be both functional and secure.

Frequently Asked Questions

Share this article

XLinkedIn

Related Posts