Linux File Permissions Explained

You copy a script to a server, run it, and get “Permission denied”. You open a log file and get the same message. Both come down to the same thing: every file in Linux carries a set of permission bits, and the system checks them before it lets you near the file.
In Linux, file permissions, attributes, and ownership control the access level that system processes and users have to files. This ensures that only authorized users and processes can access specific files and directories.
This guide explains how to read the permission bits in ls -l output, what read, write, and execute mean on files and on directories, and how to change permissions with chmod using both symbolic and numeric modes. It also shows how Linux decides which permissions apply and how to track down the cause of a “Permission denied” error.
To convert between symbolic and numeric modes while you read, try the interactive chmod calculator .
Linux File Permissions
The basic Linux permissions model works by associating each system file with an owner and a group and assigning permission access rights for three different classes of users:
- The file owner.
- The group members.
- Others (everybody else).
File ownership can be changed using the chown
and chgrp
commands.
Three permission types apply to each class of users:
- The read permission.
- The write permission.
- The execute permission.
This concept allows you to control which users can read the file, write to the file, or execute the file.
To view the file permissions, use the ls
command:
ls -l file_name-rw-r--r-- 1 linuxize users 12288 Apr 28 10:10 file_name
|[-][-][-]
| | | |
| | | +----------------------------> 4. Others Permissions
| | +-------------------------------> 3. Group Permissions
| +----------------------------------> 2. Owner Permissions
+------------------------------------> 1. File TypeThe first character indicates the file type. It can be a regular file (-), directory (d), a symbolic link
(l), or another special file type. The following nine characters represent the file permissions, arranged as three triplets. The first triplet shows the owner permissions, the second shows the group permissions, and the last shows the permissions for everybody else.
An optional character can appear immediately after the permission bits. A + usually indicates an access control list, while a . indicates a security context without another alternate access method. When neither applies, ls leaves this position blank. The remaining fields show the hard-link count, owner, group, size, modification time, and file name.
In the example above, rw-r--r-- means that the file owner has read and write permissions (rw-), and the group and others have only read permissions (r--).
Each of the three permission triplets can be built from the following characters, and the same character means different things depending on whether it is set on a file or on a directory:
Effect of Permissions on Files
Effect of Permissions on Directories (Folders)
Directories are special types of files that can contain other files and directories.
Directory Permissions in Practice
The difference between read and execute on a directory is easier to see with a quick test. Run these commands as a regular user, without sudo. Create a directory with a file inside it, and then set the directory mode to 600:
mkdir reports
echo "q3 totals" > reports/summary.txt
chmod 600 reportsWith mode 600, you have read permission on the directory but no execute permission. You can still list the names inside it:
ls reportssummary.txtOpening the file fails. Without execute permission, you cannot reach anything inside the directory:
cat reports/summary.txtcat: reports/summary.txt: Permission deniedA long listing shows the same limit. ls can read the names but not the file details, and it prints question marks in place of the permissions, owner, size, and date:
ls -l reportstotal 0
-????????? ? ? ? ? ? summary.txtThe output above comes from Ubuntu 26.04. GNU ls, used on Debian, Fedora, and older Ubuntu releases, also prints a cannot access error for each entry.
Next, give the owner execute permission without read permission:
chmod 100 reportsThis time, listing the directory fails:
ls reportsls: cannot open directory 'reports': Permission deniedThe file is still reachable if you know its name:
cat reports/summary.txtq3 totalsMost directories need both bits. The common directory modes, 755 and 700, give the owner read and execute access. To restore normal access to the test directory, run chmod 755 reports.
How Linux Checks Permissions
When a process tries to open a file, the kernel compares the user and groups of that process with the file’s owner and group. For a file without an extended access control list (ACL), it picks exactly one permission triplet:
- If you own the file, the owner permissions apply.
- If you do not own the file but belong to its group, the group permissions apply.
- In every other case, the permissions for others apply.
The check stops at the first match. The triplets do not add up, and an owner can end up with fewer rights than everybody else. The following file gives its owner no permissions and gives the group and others full access:
ls -l notes.txt----rwxrwx 1 linuxize linuxize 14 Nov 10 21:01 notes.txtThe owner, linuxize, cannot read it:
cat notes.txtcat: notes.txt: Permission deniedOther users can read the file even though the owner cannot. As the owner, you can still fix the mode with chmod 644 notes.txt. The right to change permissions comes from ownership, not from the permission bits.
Group membership comes from your user account. To list the groups of your current shell, use the id
command:
id -nGIf the file’s group is in that list and you are not the owner, the group triplet applies. To give a user access through a group, add the user to it as shown in our guide on adding a user to a group .
The root user is the exception to these rules. Root can normally bypass file read and write permission checks, but other restrictions, such as a read-only file system, can still prevent access. Running a file is different. Root still needs the execute bit set for at least one class, and a script with mode 644 cannot be run directly, even by root.
Changing File Permissions
File permissions can be changed using the chmod command. Only the file owner or root (directly or through sudo) can change the permissions of a file. Be extra careful when using chmod, especially when changing permissions recursively. The command can accept one or more files and/or directories separated by spaces as arguments.
Permissions can be specified using a symbolic mode, numeric mode, or a reference file.
Symbolic (Text) Method
The syntax of the chmod command when using the symbolic mode has the following format:
chmod [OPTIONS] [ugoa…][-+=]perms…[,…] FILE...The first set of flags ([ugoa…]), called user flags, defines the user classes whose permissions will be changed.
u- The file owner.g- The users who are members of the group.o- All other users.a- All users, identical tougo.
When the user class is omitted, chmod treats it like a, except that permissions masked by the current umask are not affected.
The second set of flags ([-+=]), the operation flags, defines whether the permissions are to be removed, added, or set:
-- Removes the specified permissions.+- Adds specified permissions.=- Changes the current permissions to the specified permissions. If no permissions are given after the=symbol, all permissions from the specified user class are removed.
The permissions (perms...) are set using zero or more of the following letters: r, w, x, X, s, and t. Use a single letter from the set u, g, and o when copying permissions from one user class to another.
When setting permissions for more than one user class ([,…]), use commas (without spaces) to separate the symbolic modes.
Here are some examples of how to use the chmod command in symbolic mode:
Give the members of the group permission to execute the file, but not to read and write to it:
Terminalchmod g=x filenameRemove the write permission for all users:
Terminalchmod a-w filenameRecursively remove the execute permission for other users:
Terminalchmod -R o-x dirnameRemove the read, write, and execute permission for all users except the file’s owner:
Terminalchmod og-rwx filenameThe same thing can also be accomplished by using the following form:
Terminalchmod og= filenameGive read, write, and execute permission to the file’s owner, read permission to the file’s group, and no permissions to all other users:
Terminalchmod u=rwx,g=r,o= filename
Numeric Method
The syntax of the chmod command when using the numeric mode has the following format:
chmod [OPTIONS] NUMBER FILE...When using the numeric mode, you can set the permissions for all three user classes (owner, group, and all others) at the same time.
The permission number can be a 3-digit or 4-digit number. When a 3-digit number is used, the first digit represents the permissions of the file’s owner, the second one the file’s group, and the last one all other users.
Each read, write, and execute permission has the following numeric value:
r(read) = 4w(write) = 2x(execute) = 1- no permissions = 0
The permissions number of a specific user class is represented by the sum of the values of the permissions for that class.
To find the file’s permissions in numeric mode, calculate the total for each user class. For example, to give read, write, and execute permission to the file’s owner, read and execute permission to the file’s group, and only read permission to all other users, use the following values:
- Owner: rwx=4+2+1=7
- Group: r-x=4+0+1=5
- Others: r–=4+0+0=4
Using the method above, we get the number 754, which represents the desired permissions.
To set the setuid, setgid, and sticky bit flags, use a 4-digit number.
When a 4-digit number is used, calculate the first digit from these values:
setuid= 4setgid= 2- sticky bit = 1
- no special bits = 0
The next three digits have the same meaning as when using a 3-digit number.
If the first digit is 0, it can be omitted, and the mode can be represented with 3 digits. The numeric mode 0755 is the same as 755.
For a closer look at what these three flags do on files and on directories, and where each one is safe to use, see our guide on setuid, setgid, and the sticky bit .
You can check the file’s permissions in the numeric notation using the stat
command:
stat -c "%a" file_nameHere are some examples of how to use the chmod command in numeric mode:
Give the file’s owner read and write permissions and only read permissions to group members and all other users:
Terminalchmod 644 fileGive the file’s owner read, write and execute permissions, read and execute permissions to group members and no permissions to all other users:
Terminalchmod 750 fileGive everyone read, write, and execute permissions, plus the sticky bit, on a shared directory. Reserve this for scratch directories where every user genuinely needs to create files, and see what chmod 777 means for why the world-writable part is risky anywhere else:
Terminalchmod 1777 dirnameGive the owner read and write permission on files and full access to directories, while removing all group and other permissions throughout the directory tree:
Terminalchmod -R u=rwX,go= dirnameThe uppercase
Xadds execute permission to directories and to files that already have an execute bit. It does not make every regular file executable.
Default Permissions for New Files
You do not set permissions by hand every time you create a file. In the usual case, programs request a mode of 666 for new regular files and 777 for new directories. The system then clears the bits covered by the umask. A program can request a stricter mode, and a default ACL on the parent directory can determine the permissions instead.
Check the current mask:
umask0022With a mask of 022, the write bit is cleared for the group and for others, so a new file lands on 644 and a new directory on 755. A stricter mask of 077 clears every bit for both classes, giving 600 and 700. Our umask guide
covers how to calculate a mask and how to make it permanent.
Troubleshooting
“Permission denied” even though the file permissions look correct
Every directory in the path also needs execute permission for the user who opens the file. A common case is a web server that cannot read a site stored in a home directory. Ubuntu creates home directories with mode 750. Other users, including the www-data account that Nginx and Apache run as, get no access at all:
sudo -u www-data cat /home/linuxize/site/index.htmlcat: /home/linuxize/site/index.html: Permission deniedThe namei -l command walks the path and prints the permissions of each component:
namei -l /home/linuxize/site/index.htmlf: /home/linuxize/site/index.html
drwxr-xr-x root root /
drwxr-xr-x root root home
drwxr-x--- linuxize linuxize linuxize
drwxrwxr-x linuxize linuxize site
-rw-rw-r-- linuxize linuxize index.htmlThe file itself is readable by others, but /home/linuxize gives others no execute permission. Move the files to a directory such as /var/www, or let only www-data pass through the home directory with an access control list:
sudo setfacl -m u:www-data:x /home/linuxizewww-data can now reach the files inside, but it still cannot list the contents of the home directory.
“Permission denied” when running a script
The script needs the execute bit. Add it for the owner with chmod u+x script.sh. If the bit is already set, the file system may be mounted with the noexec option. Check the mount options of the file system containing the script with findmnt -T /path/to/script.sh -o TARGET,OPTIONS, replacing /path/to/script.sh with the script’s actual path.
Access still denied after adding a user to a group
Group membership is read at login. A shell that was open before the change keeps the old group list. Compare the output of id -nG with id -nG username. The second command reads the group database and shows the new group. Log out and back in, or run newgrp groupname to start a shell with the new group.
ls -l shows question marks instead of permissions
You have read permission on the directory but not execute permission. ls can read the file names but cannot look up their details. Add execute permission to the directory, for example with chmod u+x dirname.
The permissions look correct, but access is different than expected
A + after the permission bits in ls -l output means the file has an access control list (ACL). ACL entries can grant or limit access for specific users and groups beyond the owner, group, and others classes. With an extended ACL, the group triplet shown by ls -l represents the ACL mask, which limits the permissions available to named users and groups, including the file’s group. View the entries and their effective permissions with getfacl filename.
Quick Reference
For a printable quick reference, see the chmod cheatsheet .
Common permission values:
| Mode | Symbolic | Who can do what |
|---|---|---|
777 | rwxrwxrwx | Everyone can read, write, and execute |
755 | rwxr-xr-x | Owner full access; group and others read and execute |
750 | rwxr-x--- | Owner full access; group read and execute; others none |
700 | rwx------ | Owner full access; group and others none |
664 | rw-rw-r-- | Owner and group read/write; others read only |
644 | rw-r--r-- | Owner read/write; group and others read only |
600 | rw------- | Owner read/write; group and others none |
400 | r-------- | Owner read only; group and others none |
Symbolic chmod examples:
| Command | Effect |
|---|---|
chmod u+x file | Add execute for owner |
chmod g-w file | Remove write for group |
chmod o= file | Remove all permissions for others |
chmod a+r file | Add read for everyone |
chmod u=rwx,g=rx,o= file | Set exact permissions for all classes |
chmod -R u=rwX,go=rX dir | Give everyone directory access without making every file executable |
FAQ
What is the difference between chmod and chown?chmod
changes the permission bits (read, write, execute) on a file. chown
changes the file’s owner and group. Both affect who can access the file, but they control different aspects.
What does chmod 777 mean and is it safe?777 gives read, write, and execute permission to the owner, group, and all other users. It is rarely appropriate and should be avoided on files that contain sensitive data or are executable by services, as it allows anyone on the system to modify or run them.
Why does a directory need execute permission?
On a directory, execute permission allows you to enter it and access items inside it by name. Without execute permission, you can list the directory contents only in limited cases, but you cannot traverse it with commands such as cd or open files within it.
What is the sticky bit and when should I use it?
On a writable, searchable directory, the sticky bit (mode 1xxx, shown as t in ls -l) allows only the file’s owner, the directory’s owner, or root to delete or rename a file inside it. It is used on shared directories like /tmp to prevent users from deleting each other’s files.
What is setuid and why is it dangerous?
When set on an executable program, setuid causes it to run with the owner’s privileges rather than the caller’s. For example, /usr/bin/passwd is setuid root so ordinary users can change their own password. A poorly designed setuid program can create a privilege escalation risk. Linux ignores the setuid and setgid bits on interpreted scripts.
How do I view permissions in numeric mode?
Use the stat
command: stat -c "%a %n" file. It prints the octal permission value alongside the filename.
Conclusion
In Linux, access to files is controlled through permission bits assigned to three classes: owner, group, and others. Use chmod with symbolic or numeric mode to change permissions, and ls -l or stat to inspect them. For a focused command reference, see the chmod command guide
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page