You are currently viewing Linux File Permissions: A Practical Guide to chmod, Ownership, and Safe Access

Linux File Permissions: A Practical Guide to chmod, Ownership, and Safe Access

A private SSH key with permissions such as -rw-r--r-- can be read by every local account, even though only its owner should use it. Linux file permissions help prevent this kind of accidental exposure. They control who can read a file, modify it, run it as a program, or access a directory.

Each file and directory has an owner, an associated group, and a set of permission bits. Knowing how to inspect and adjust those bits matters when working with source code, scripts, configuration files, shared project folders, and personal data.

Reading the permission string

Run ls -l in a terminal to see a long listing:

$ ls -l deploy.sh notes.txt projects
-rwxr-x--- 1 alex developers  820 Mar 12 09:10 deploy.sh
-rw-r--r-- 1 alex developers 1240 Mar 12 09:14 notes.txt
drwxr-x--- 3 alex developers 4096 Mar 12 09:20 projects

The first column is the permission string. Its first character identifies the item type:

  • - indicates a regular file.
  • d indicates a directory.
  • l indicates a symbolic link.

The following nine characters are divided into three groups:

Position Applies to Example
Characters 2–4 Owner (user) rwx
Characters 5–7 Group r-x
Characters 8–10 Others ---

In -rwxr-x---, the owner can read, write, and execute the file. Members of the file’s group can read and execute it, while everyone else has no access. The owner and group appear after the link count, so alex developers identifies the owner and associated group in the example.

Terminal output showing Linux permission groups

What read, write, and execute actually mean

The letters are r for read, w for write, and x for execute. A dash means the permission is missing. The same letters behave somewhat differently on regular files and directories.

Permissions on regular files

  • Read (r): allows the file’s contents to be viewed. For example, cat notes.txt requires read permission.
  • Write (w): allows the file’s contents to be changed or truncated, though directory permissions still affect whether the file can be replaced or deleted.
  • Execute (x): allows a file to run as a program or script. A shell script normally needs both a valid interpreter line, such as #!/bin/bash, and execute permission before ./script.sh will work.

Adding the execute bit does not make a text file safe or useful to run. Do not mark downloaded files as executable unless you trust both their source and contents.

Permissions on directories

Directories store filename-to-file mappings, so their permissions work differently in practice:

  • Read: allows directory names to be listed, such as with ls.
  • Write: allows entries in the directory to be created, deleted, or renamed.
  • Execute: also called search permission, allows you to enter the directory and access items whose names you know.

Directory write permission deserves special attention. Deleting a file is controlled mainly by the directory that contains it, not by the file’s own write bit. A read-only file can still often be removed or renamed by someone who can write to its parent directory.

A directory with r-- but no execute permission may reveal a list of names while blocking normal access to the files inside. A directory with --x can permit access to a known filename without allowing a full listing. These settings can be useful in specialized shared environments, though personal directories usually use simpler permission schemes.

Owner, group, and others

Linux checks permissions in a fixed order. If a process runs as the file owner, Linux applies the owner permissions. Otherwise, if the process belongs to the file’s group, it applies the group permissions. If neither applies, Linux uses the permissions for others. Rights from these categories are not combined.

Suppose a file is -rw-r----- and belongs to user alex and group developers:

  • alex can read and edit the file.
  • Other members of developers can read it but cannot edit it.
  • Users outside that group cannot access it.

Use id or groups to check your account’s groups. On a multi-user system, groups are usually a cleaner way to share project access than repeatedly changing ownership between individual accounts.

Changing permissions with chmod

The chmod command changes mode bits. Symbolic notation is easy to read and works well for small, deliberate changes.

chmod u+x deploy.sh
chmod g-w shared-notes.txt
chmod o-r private-key.pem

In symbolic notation, u means user or owner, g means group, o means others, and a means all three. The operators +, -, and = add, remove, or set permissions. For example, chmod u+x deploy.sh allows only the owner to execute the script without changing its other permission bits.

Numeric notation

Numeric modes represent each permission group with a number. Read is 4, write is 2, and execute is 1. Add the values within each group:

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

The familiar command chmod 755 script.sh gives the owner rwx and gives the group and others r-x. With chmod 644 document.txt, the owner gets rw-, while the group and others get read-only access.

These are common defaults, not universal rules. A local development script may reasonably use 700 if only its owner needs to run it. A configuration file containing credentials should usually be more restrictive, often 600, so only its owner can read or edit it.

Careful permission changes on a project file

Ownership: chown and chgrp

Permissions do not solve every access problem. If a file has the wrong owner or group, change that metadata with administrative authorization when appropriate:

sudo chown alex report.txt
sudo chown alex:developers project-config.yml
sudo chgrp developers shared-project

chown changes the owner and can set the group after a colon. chgrp changes only the group. Use sudo carefully: it grants elevated authority, and one incorrect recursive command can affect a large part of the system. Before changing ownership on personal files, inspect the path with ls -ld path and confirm that the change is actually needed.

Recursive changes and why they need caution

chmod -R applies changes throughout a directory tree. It may look like a quick fix, but applying one mode to files and directories alike can cause problems. For example, chmod -R 644 project removes execute permission from directories, making them inaccessible. In contrast, chmod -R 755 project makes every source file executable for no good reason.

When files and directories need different modes, use find only on a directory you own and have checked:

find project -type d -exec chmod 755 {} ;
find project -type f -exec chmod 644 {} ;

This example gives directories permissions that allow traversal and gives ordinary files standard read/write permissions. Do not copy it blindly into shared or sensitive directories, since it can make content readable to other local users. For a private code workspace, 750 for directories and 640 for files may better fit the intended group policy.

Special modes: setuid, setgid, and the sticky bit

Linux also has special permission bits, shown as s or t in long listings. You should recognize them even if you rarely set them yourself.

  • setuid: an executable runs with the file owner’s effective privileges. Because this can grant elevated capability, it should be used only by trusted, deliberately installed system programs.
  • setgid: on a directory, newly created items commonly inherit that directory’s group. This can be useful for a controlled team workspace.
  • sticky bit: on a shared writable directory, users can generally delete only entries they own. The conventional /tmp directory often has permissions similar to drwxrwxrwt.

Avoid adding setuid or setgid to executables as a shortcut around access errors. Correct ownership, group membership, or application configuration is safer than expanding privileges.

Permissions are not the whole access-control system

Traditional mode bits are only one layer of Linux access control. Access control lists (ACLs) can grant extra rights to specific users or groups. Mandatory access-control systems such as SELinux or AppArmor may restrict a process even when basic permissions appear correct. Network-mounted filesystems and container environments can add their own rules too.

If ls -l shows an unexpected + after the permission string, ACLs may be present. On systems where it is installed, use getfacl filename to inspect them. When troubleshooting, check every parent directory as well: accessing /home/alex/project/config.yml requires execute permission on /home, /home/alex, and /home/alex/project, not just permission on config.yml.

For a newly created private credential file, run chmod 600 credential-file, then verify it with ls -l credential-file. The result should begin with -rw-------, which means only the owner can read or modify the file.