Every file on a Linux system carries a short tag that decides who may read it, change it, or run it. Beginners glance at letters like rwxr-xr-x and scroll past. Then a script refuses to run, a web server returns 403, or ssh rejects a key you just copied, and that tag is the reason every single time.
Run ls -l on a few files and the tag is the first thing on each line:
$ ls -l /usr/bin/passwd deploy.sh notes.txt
-rwsr-xr-x 1 root root 68208 Mar 23 2025 /usr/bin/passwd
-rwxr-xr-x 1 priya priya 412 Jul 1 09:14 deploy.sh
-rw-r--r-- 1 priya priya 980 Jul 1 09:15 notes.txt
Read the first column left to right. The opening character is the file type, a plain - for a normal file. The next nine characters are three groups of three: what the owner may do, what the file group may do, and what everyone else may do. In notes.txt the owner can read and write, the group can only read, and so can the rest of the world.
Every file has an owner, a group, and three sets of permissions: owner, group, everyone else. Each set has three switches: read, write, execute. Turn them into numbers with 4 for read, 2 for write, 1 for execute, add them up inside each set, and you get the octal you hand to
chmod. 644 is a normal file, 755 is a program or a directory you can enter, 600 is a private key. That is most of the job.Two readers, one page. If you are on a home VM after a computer science degree, create the files below and flip their bits by hand until the output stops surprising you. If you already run boxes for a living and want the parts people get wrong, jump to the directory execute bit and the recursive chmod section, because that is where real outages start. Everything here is identical on Ubuntu, Debian, and the RHEL family.
Read a permission line
The nine permission characters are always in the same order and always mean the same thing. A letter means the switch is on, a dash means off. The left group is the owner, the middle group is the file group, the right group is everyone else. Read sits in slot one of each group, write in slot two, execute in slot three.
The s sitting where an x should be on /usr/bin/passwd is a special bit, not a typo. Hold that thought until the closing questions.
The bits, and why a directory is different
On a file the three switches read the way you would guess. Read lets you see the contents, write lets you change them, execute lets you run the file as a program. On a directory the same three letters mean something else, and this is the single most common permission mistake in the wild.
What read, write and execute do to a directory
On a directory, read lets you list the names inside. Execute, often called the search or traverse bit, lets you enter the directory and reach the files inside by name. Write lets you create and delete entries. The catch is that read without execute is close to useless: you get a bare list of names but cannot cd in or open anything. Execute without read is the opposite and genuinely handy, because you can reach a file if you already know its exact name while the listing stays hidden.
$ chmod 644 project # read on, execute off
$ ls project
ls: cannot access 'project/report.txt': Permission denied
report.txt
$ cd project
bash: cd: project: Permission denied
$ chmod 755 project # execute back on
$ cd project && echo in
in
This is why a web directory left at 644 throws errors while 755 serves fine, and why the fix for a puzzling Permission denied on a path is so often a missing execute bit on a parent directory rather than on the file itself.
A user reports that a shared folder is broken: they can see the file names but every open fails with Permission denied. Nine times out of ten the directory is 644 or 640, so read is on and execute is off. They can list the entries but cannot traverse into the directory to reach the data. Add execute for the group with
chmod g+x on the directory, not the files, and it works. Setting the files to 777 in frustration does nothing, because the block was never on the files.Octal, saying rwx in one digit
Typing rwxr-xr-x gets old, so Linux lets you hand chmod a number instead. Give read the value 4, write 2, execute 1, then add them up inside each group of three. Read plus write plus execute is 4 plus 2 plus 1, which is 7. Read plus execute is 4 plus 1, which is 5. Read alone is 4. Three groups give three digits, so rw-r--r-- is 644 and rwxr-xr-x is 755.
| Octal | Letters | Meaning |
|---|---|---|
| 0 | — | nothing |
| 1 | –x | execute only |
| 2 | -w- | write only |
| 3 | -wx | write and execute |
| 4 | r– | read only |
| 5 | r-x | read and execute |
| 6 | rw- | read and write |
| 7 | rwx | read, write, execute |
A lot of guides hand you a table of all eight values to memorize. Skip that. Memorize three numbers, 4, 2, 1, and add them in your head. Once you can do that, every mode from 000 to 777 is obvious and you will never reach for a lookup again. The table above is a check, not a thing to learn by heart.
chmod, by symbol or by number
chmod takes either form. Numeric sets all three groups at once and is what you will use most: chmod 644 notes.txt. Symbolic changes one switch and leaves the rest alone, which is safer when you only mean to touch one thing. chmod +x deploy.sh turns on execute for everyone, chmod u+x deploy.sh only for the owner, and chmod go-w notes.txt removes write from group and others without disturbing read.
| Symbol | Means | Example |
|---|---|---|
| u g o a | owner, group, others, all | chmod g+w file |
| + – = | add, remove, set exactly | chmod o= file |
| r w x | read, write, execute | chmod u+x script |
| X | execute on directories and files that already have it | chmod -R go+rX dir |
$ ./deploy.sh
bash: ./deploy.sh: Permission denied
$ ls -l deploy.sh
-rw-r--r-- 1 priya priya 412 Jul 1 09:14 deploy.sh
$ chmod +x deploy.sh
$ ls -l deploy.sh
-rwxr-xr-x 1 priya priya 412 Jul 1 09:14 deploy.sh
$ ./deploy.sh
deploy: starting
$ stat -c '%a %n' deploy.sh
755 deploy.sh
The failure is the first line. A shell script is just text until the execute bit is set, and the kernel refuses to run a file it is not allowed to execute, even one you own outright. stat -c '%a' prints the mode as the octal number, which is the quickest way to confirm a change without decoding letters by eye.
On a test VM, prove you can read a mode without guessing. Run these four lines:
touch demo.txtchmod 640 demo.txtstat -c '%a %A %n' demo.txtThe exact check: the output must begin with
640 -rw-r-----. If the number and the letters disagree, you misread one group. Change it to 644 with chmod o+r demo.txt and run the stat line again to watch the last group flip.umask, the permissions you never chose
You never type chmod on most files you create, yet they come out 644 and new directories come out 755. That is umask at work. When a program creates a file it asks for a generous default, 666 for files and 777 for directories, and the umask strips bits off that request. The common default umask is 022, which removes write from group and others.
$ umask
0022
$ touch fresh.txt && mkdir freshdir
$ stat -c '%a %n' fresh.txt freshdir
644 fresh.txt
755 freshdir
The arithmetic is a subtraction of permission bits. 666 minus 022 gives 644, and 777 minus 022 gives 755. Execute is never granted to a new file even though the base is 666, which is deliberate, so a downloaded text file cannot run itself. On Debian and Ubuntu a normal user often gets umask 002, because each user has a private group of their own, which is why files you create there can be group writable. Check yours with a bare umask before you assume.
The recursive chmod that breaks things
chmod has a -R flag that walks a whole tree. It is useful and it is dangerous, because the same number gets stamped on files and directories alike, and files and directories want different execute bits.
The advice you will see on forums is chmod -R 777 to make a permission error go away. Do not do it. 777 gives every account on the box full write and execute on every file, turns plain data files into executables, and on a web server it is the first thing an attacker checks for, because any uploaded file becomes runnable. It hides the symptom and opens a hole.
When you truly need to fix a tree, reach for the capital X. chmod -R u=rwX,go=rX . gives read and write to the owner and read to everyone else, and the capital X adds execute only to directories and to files that already had an execute bit. Directories become traversable, ordinary files stay non executable, and it is one command. In a recursive chmod, the lowercase x is the trap and the capital X is the tool you want.
The sharpest everyday example is ssh. Copy a private key with loose bits and the client refuses to use it at all:
$ ssh -i id_rsa deploy@server
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
$ chmod 600 id_rsa
$ ssh -i id_rsa deploy@server
deploy@server:~$
ssh checks the key file itself and rejects anything a group or other user could read, because a private key readable by others is a leaked key. The fix is 600, owner read and write only, or 400 for read only. The .ssh directory should be 700 for the same reason.
What is the difference between
chmod 644 and chmod 755, and when would you use each? A strong answer: 644 is read and write for the owner and read for group and others, right for data files like text, images, and config. 755 adds execute for everyone, which you want on programs and scripts, and on directories, where execute means the ability to enter and traverse. If you can add that a plain file rarely needs execute and that 755 on a directory is what lets users reach the files inside, you are past the beginner line.Ownership is a separate lever
Permissions decide what the owner, the group, and others may do. They say nothing about who the owner and group actually are. That job belongs to chown, and confusing the two is a classic time sink. A file can carry perfect 644 bits and still block you, because you are not the owner and the owner class is the only one with write.
$ echo test > /var/www/site/config.php
bash: /var/www/site/config.php: Permission denied
$ ls -ld /var/www/site
drwxr-xr-x 2 root root 4096 Jul 1 10:02 /var/www/site
$ sudo chown -R www-data:www-data /var/www/site
$ sudo -u www-data touch /var/www/site/config.php
$ ls -l /var/www/site/config.php
-rw-r--r-- 1 www-data www-data 0 Jul 1 10:03 /var/www/site/config.php
The directory was owned by root, so a normal user could read and traverse it but not create files inside. No amount of chmod on the files would help, because the block was ownership, not mode. chown user:group sets both owner and group at once, and -R walks the tree. When a Permission denied makes no sense against the bits you can see, check the owner with ls -l before you reach for chmod.
Common questions
What is the difference between chmod 644 and 755?
644 is read and write for the owner and read for the rest, right for data files. 755 adds execute for everyone, right for programs and for any directory you need to enter. Use 644 for files, 755 for directories and scripts.
It worked when I set 777, so why not leave it?
Because 777 also lets any account on the machine rewrite your files and run them, which removes the protection permissions exist to give. If 777 fixed it, the real cause was almost always a missing execute bit on a directory, and 755 on that directory solves it safely.
What are the s and t letters I sometimes see?
An s in the owner slot is setuid, which runs the program as its owner rather than as you, and it is how passwd can edit a root owned file. An s in the group slot is setgid. A t on a directory is the sticky bit, used on /tmp so users can delete only their own files. Real bits with real uses, and a later part goes deeper.
Do permissions differ on Ubuntu and RHEL?
The letters, the numbers, chmod and umask are identical across distributions. The differences sit elsewhere, such as the default umask a user gets and which group grants admin access. The permission model itself is the same everywhere.
Permissions are the gate. The next part is about the programs that walk through it, how Linux starts, tracks, and stops the processes running on a box. Working the whole path from the start? Begin at the Linux for Beginners guide. To see where these same files and bits sit on rented machines, the Cloud for Beginners series picks up there, and the VMware for Beginners series covers the hardware underneath.
References
chmod(1) manual page, symbolic and numeric modes
umask(2), how the creation mask is applied
ssh(1), why private key files must stay private


DrJha