Linux file permissions are one of the first things that confuse newcomers. When you run ls -l in the terminal, you see a string like -rwxr-xr-x at the start of each line. What does that mean? And what does it mean when someone tells you to run chmod 755?
This guide explains the permission system from scratch, with real-world examples that make it easy to understand and use.
Why Linux has a permissions system
Linux is designed as a multi-user operating system. Multiple people can have accounts on the same machine, and the operating system needs a way to enforce who can access what.
The permission system does three things:
- Prevents users from reading each other’s private files
- Prevents regular users from accidentally (or maliciously) modifying system files
- Controls which files can be executed as programs
Even on a computer used by a single person, these protections matter. They prevent malware from modifying system files, and they prevent mistakes — like accidentally deleting /etc/ configuration files without root access.
Reading the permission string
Run ls -l in any directory and you see output like this:
ls -l
# -rwxr-xr-x 1 alice developers 4096 Jan 15 09:30 script.sh
# drwxr-xr-x 2 alice alice 4096 Jan 14 12:00 Documents/
# -rw-r--r-- 1 alice alice 2048 Jan 13 18:45 notes.txt
Let us decode the first column, the permission string. Take -rwxr-xr-x as an example.
The string has 10 characters:
- Character 1: file type.
-means a regular file,dmeans a directory,lmeans a symbolic link - Characters 2-4: permissions for the owner of the file
- Characters 5-7: permissions for the group
- Characters 8-10: permissions for others (everyone else)
So -rwxr-xr-x means:
-— it is a regular filerwx— the owner can read, write, and executer-x— group members can read and execute (but not write)r-x— everyone else can read and execute (but not write)
The three permission levels: owner, group, others
Every file in Linux has exactly one owner (a user) and one group. The permission system applies different rules to three categories of people:
Owner: The user who owns the file. By default, this is the user who created the file. The owner can be changed with chown.
Group: A named group of users. Files have a group associated with them. All members of that group share the same “group” permissions. Groups are useful for sharing files between specific users — for example, a developers group might have write access to a shared code repository.
Others: Everyone else — any user on the system who is not the owner and is not in the file’s group.
Linux checks these categories in order: if you are the owner, the owner permissions apply and the check stops. If you are in the file’s group (but not the owner), group permissions apply. Otherwise, “others” permissions apply.
Read, write and execute explained
Each of the three permission groups (owner, group, others) can have up to three permission types:
r — Read
- For files: you can view the file’s contents
- For directories: you can list the directory’s contents with
ls
w — Write
- For files: you can modify or delete the file
- For directories: you can create, delete, or rename files inside the directory
x — Execute
- For files: you can run the file as a program or script
- For directories: you can enter the directory with
cdand access files inside it
A - in place of a letter means that permission is not granted.
Important note about directories: to access files inside a directory, you need execute (x) permission on the directory, not just read (r). Read without execute lets you list the directory but not access the files inside it.
Changing permissions with chmod
The chmod command (change mode) modifies file permissions. There are two ways to use it: symbolic notation and numeric (octal) notation.
Symbolic notation uses letters to specify changes:
chmod u+x script.sh # add execute permission for the owner (u = user/owner)
chmod g+w file.txt # add write permission for the group
chmod o-r secret.txt # remove read permission for others
chmod a+r public.txt # add read for all (a = all: owner, group, others)
chmod go-wx file.txt # remove write and execute from group and others
The format is: who operation permission
- Who:
u(owner/user),g(group),o(others),a(all) - Operation:
+(add),-(remove),=(set exactly) - Permission:
r,w,x
To apply permissions recursively to all files in a directory:
chmod -R 644 /var/www/html/
Numeric (octal) permissions
Numeric notation assigns a number to each permission combination. This is what people mean when they say chmod 755 or chmod 644.
Each permission type has a numeric value:
r= 4w= 2x= 1- no permission = 0
You add these values for each group:
| Combination | Calculation | Meaning |
|---|---|---|
--- | 0+0+0 = 0 | no permissions |
--x | 0+0+1 = 1 | execute only |
-w- | 0+2+0 = 2 | write only |
-wx | 0+2+1 = 3 | write and execute |
r-- | 4+0+0 = 4 | read only |
r-x | 4+0+1 = 5 | read and execute |
rw- | 4+2+0 = 6 | read and write |
rwx | 4+2+1 = 7 | all permissions |
A three-digit number combines the values for owner, group, and others:
chmod 755 script.sh # owner=rwx(7), group=r-x(5), others=r-x(5)
chmod 644 file.txt # owner=rw-(6), group=r--(4), others=r--(4)
chmod 600 private.key # owner=rw-(6), group=---(0), others=---(0)
chmod 777 shared/ # everyone has full access (avoid on web servers)
Common permission combinations:
755— standard for directories and executable scripts644— standard for regular files (documents, config files)600— private files (SSH keys, credential files)700— private directories and scripts
The chown command
chown (change owner) changes who owns a file or directory.
sudo chown alice file.txt # change owner to alice
sudo chown alice:developers file.txt # change owner and group
sudo chown :developers file.txt # change only the group
sudo chown -R www-data /var/www/ # change owner recursively
You almost always need sudo to run chown, because changing ownership of files requires root privileges.
The chgrp command changes just the group:
sudo chgrp developers project/
Special permissions: setuid, setgid and sticky bit
Beyond the standard rwx permissions, Linux has three special permission bits.
Setuid (SUID) — on an executable file, this means the program runs with the permissions of the file’s owner rather than the user running it. The passwd command uses this to allow regular users to change their own password (which requires modifying /etc/shadow, a root-owned file).
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 59976 ... /usr/bin/passwd
# Note the 's' in the owner execute position instead of 'x'
Set SUID: chmod u+s filename or chmod 4755 filename
Setgid (SGID) — on a directory, new files created inside inherit the directory’s group rather than the creator’s primary group. Useful for shared project directories.
chmod g+s shared-project/
chmod 2755 shared-project/
Sticky bit — on a directory, prevents users from deleting files they do not own, even if they have write permission on the directory. The /tmp directory uses this.
ls -ld /tmp
# drwxrwxrwt 1 root root ... /tmp
# Note the 't' at the end instead of 'x'
chmod +t shared-dir/
chmod 1777 shared-dir/
Practical examples
Making a shell script executable:
nano deploy.sh # write your script
chmod +x deploy.sh # make it executable
./deploy.sh # run it
Setting up a web server directory:
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 755 /var/www/html/
sudo chmod -R 644 /var/www/html/*.html
Creating a shared directory for a team:
sudo mkdir /home/shared
sudo chown root:developers /home/shared
sudo chmod 2775 /home/shared # setgid + rwxrwxr-x
Protecting a private key file:
chmod 600 ~/.ssh/id_rsa # SSH requires this exact permission
Checking what permissions a file has:
ls -l filename
stat filename # more detailed information
Common permission problems and solutions
“Permission denied” when running a script: The file is not executable. Fix: chmod +x script.sh
“Permission denied” when editing a system file: The file requires root access. Fix: sudo nano /etc/filename
SSH says “Permissions are too open” for a key file: SSH refuses to use private keys that others can read. Fix: chmod 600 ~/.ssh/id_rsa
Apache/Nginx returns 403 Forbidden: The web server cannot read your files. Check that files are 644 and directories are 755, and that the web server user (www-data) has access. Also check that all parent directories have execute permission for www-data.
Can’t delete a file you don’t own in /tmp: This is the sticky bit working as intended. You can only delete files you own in sticky-bit directories, regardless of write permission on the directory.
Understanding permissions unlocks a deeper understanding of Linux security. Combined with what you learned in understanding the Linux file system, you now have a solid foundation for managing any Linux system.