Linux · Guide
Linux File Permissions Explained (chmod and chown)
Every file and folder in Linux carries three sets of permissions — for its owner, its group and others — and each set can allow read, write and execute. You view them with ls -l, change them with chmod in either numeric form (chmod 755 file) or symbolic form (chmod u+x file), and change who owns a file with chown. Master those three commands and you understand Linux permissions.
Coming from Windows, this feels different: there is no "Properties → Security" tab full of ACL
checkboxes to wade through for everyday tasks. The classic Unix model is smaller and, once it clicks,
quicker to reason about. This guide walks through it from the ground up, with examples you can paste into
a terminal. The commands here are the same across the major distributions — Ubuntu and Debian, Fedora,
Arch, openSUSE — because chmod and chown come from GNU coreutils, which every
mainstream distro ships. Where something genuinely differs by distro, we say so.
The three "who"s and the three "what"s
Permissions answer two questions at once — who is asking, and what they are allowed to do. There are three categories of "who":
- User (
u) — the file's owner. - Group (
g) — the file's assigned group; every member of that group shares these permissions. - Others (
o) — everyone else on the system.
And three things each category can be granted:
- Read (
r) — view the file's contents, or list a directory's entries. - Write (
w) — change the file, or add and remove files inside a directory. - Execute (
x) — run the file as a program or script, or enter a directory (cdinto it and reach the files within).
On a directory, the bits mean something slightly different: r lets you list the names
inside, w lets you create or delete entries, and x lets you pass through the
directory to reach its contents. A directory almost always needs x to be useful — a folder
that is readable but not executable will show a name yet refuse to let you open what is inside.
Reading ls -l output
Run ls -l in any directory and each line starts with a ten-character block that encodes
everything:
$ ls -l
-rw-r--r-- 1 alice staff 2048 Aug 7 09:14 notes.txt
drwxr-xr-x 2 alice staff 4096 Aug 7 09:15 projects
-rwxr-xr-x 1 alice staff 8123 Aug 7 09:16 backup.sh
Take that first block apart, character by character, using -rwxr-xr-x from
backup.sh:
- Position 1 — the file type:
-is a regular file,da directory,la symbolic link. - Positions 2–4 (
rwx) — the owner's permissions: read, write, execute. - Positions 5–7 (
r-x) — the group's permissions: read, no write, execute. - Positions 8–10 (
r-x) — others' permissions: read, no write, execute.
A dash in any slot simply means "that permission is off". After the permission block, the columns you
care about most are the third and fourth: the owner (alice) and the
group (staff). Those are exactly what chown changes.
Numeric mode: chmod 755
Each permission has a value: read = 4, write = 2, execute = 1. Add them up per category and you get a single digit from 0 to 7. Three digits — one each for user, group, others — describe the whole file. That is exactly how the chmod(1) manual page defines a numeric mode: octal digits derived by adding up the bits with values 4, 2 and 1.
| Numeric | Symbolic | Means | Typical use |
|---|---|---|---|
7 | rwx | read + write + execute | owner of a script or directory |
6 | rw- | read + write | owner of a normal file |
5 | r-x | read + execute | group/others on a program or directory |
4 | r-- | read only | group/others on a data file |
0 | --- | no access | lock everyone out |
So the two modes you will type most often:
- Set a script or directory to owner-full, everyone-else read-and-run:
chmod 755 backup.sh # rwxr-xr-x - Set an ordinary data file to owner-read-write, everyone-else read-only:
chmod 644 notes.txt # rw-r--r-- - Lock a private file down to the owner alone:
chmod 600 secret.env # rw-------
Numeric mode sets all three categories at once, which makes it precise and predictable — that is why it dominates scripts and documentation. The trade-off: you must state every bit, even the ones you did not mean to touch.
Symbolic mode: chmod u+x
Symbolic mode adjusts one thing without disturbing the rest. It reads as
who + operator + what — formally
[ugoa...][[-+=][perms...]...] in the
chmod manual page's own notation:
- Who:
u(user/owner),g(group),o(others),a(all). - Operator:
+add,-remove,=set exactly (and clear the rest for that category). - What:
r,w,x.
chmod u+x deploy.sh # give the owner execute, leave everything else as-is
chmod go-w report.csv # remove write from group and others
chmod a+r public.html # let everyone read it
chmod u=rw,go=r file.txt # owner rw, group and others read-only (same as 644)
The rule of thumb: reach for numeric when you want to define the whole file's mode in one shot, and symbolic when you want to nudge a single bit — most commonly adding the execute bit to a script.
The execute bit for scripts
This is the single most common permissions task, so it earns its own section. A shell script, Python file, or any program will only run directly if its execute bit is set for you. A fresh script you just wrote, or one copied off a Windows drive or a downloaded ZIP, usually lands without it:
$ ./deploy.sh
bash: ./deploy.sh: Permission denied
$ chmod +x deploy.sh
$ ./deploy.sh
Deploying…
Plain chmod +x adds execute for user, group, and others at once (subject to your umask).
To grant it to the owner only, use chmod u+x deploy.sh. Note that a script also needs its
interpreter line — a shebang such as #!/usr/bin/env bash on the first line — for the
kernel to know how to run it.
Changing ownership with chown
Permissions are always judged relative to who owns the file, so sometimes the fix is ownership, not
bits. chown takes the form chown user:group target, and per the
chown(1) manual page
omitting the owner before the colon changes the group only — the same job as chgrp:
- Change just the owning user:
sudo chown alice notes.txt - Change owner and group together:
sudo chown alice:developers project/ - Change only the group (either
chownwith a leading colon, or usechgrp):sudo chown :developers project/ sudo chgrp developers project/ - Apply to a whole tree with
-R(recursive):sudo chown -R www-data:www-data /var/www/mysite
Changing ownership to another user requires sudo (administrator) rights — a regular user
cannot give their files away. One distro nuance worth knowing: the default web-server user and group
differ by family. Debian and Ubuntu use www-data; Fedora, RHEL and openSUSE typically use
apache (for httpd) or nginx. Check with ls -l on an existing file
in the target directory rather than guessing.
sudo, chmod -R and rm
Recursive commands are powerful and unforgiving. sudo chmod -R 777 / or a mistyped
chown -R on the wrong path can break an entire system's permissions, and there is no undo.
Two habits that save you: (1) never run chmod 777 as a reflex — it grants
everyone full control and is almost never the real fix; (2) double-check the path
before pressing Enter on anything with -R and sudo together. The same care
applies to rm -rf: it deletes recursively and permanently, with no recycle bin. Type the
path slowly, and consider running the plain ls on it first to confirm you are pointing at
what you think you are.
Common gotchas
- A readable directory you still cannot enter. If
cdfails on a folder you can see, it is missing thex(execute/"traverse") bit. Add it:chmod +x dir. - Files from Windows arriving as executable — or not. Windows filesystems have no Unix execute bit, so files copied from NTFS/FAT drives, USB sticks, or some archives come across with whatever default the mount applies. Re-set the mode explicitly after copying.
chmod -Rflattening files and directories the same way.chmod -R 755makes files executable that should not be. To set directories and files differently in one pass, usefind:find . -type d -exec chmod 755 {} +thenfind . -type f -exec chmod 644 {} +.- Editing a file you own but a tool cannot. Many services (web servers, databases)
run as their own user. A file owned by you but served by
www-datamay need achownor a shared group rather than looser permission bits. - Beyond the basics. There are three special bits — setuid,
setgid, and the sticky bit (the reason anyone can write in
/tmpbut only delete their own files) — and modern filesystems also support finer-grained POSIX ACLs viagetfaclandsetfacl. You rarely need them for everyday work, but it is good to know they exist when the three-category model is not expressive enough.
A five-minute recap
- See it:
ls -l— read the ten-character block as type + owner + group + others. - Set it (whole file):
chmod 644 file(data) orchmod 755 dir(directories and programs). - Nudge it (one bit):
chmod u+x script.shto make a script runnable. - Own it:
sudo chown user:group target, add-Rfor a whole tree.
Frequently asked
What does chmod 755 mean?
Each digit is a sum of read (4), write (2) and execute (1). 755 gives the owner 7 (4+2+1 = read, write, execute) and the group and others 5 (4+1 = read and execute). Written out by ls -l it looks like rwxr-xr-x. It is the usual mode for directories and for programs or scripts that everyone may run but only the owner may change.
What is the difference between chmod and chown?
chmod changes the permission bits — who may read, write or execute a file. chown changes ownership — which user and group the file belongs to. Permissions are always evaluated relative to ownership, so the two work together: chown decides which set of bits applies to you, and chmod decides what that set allows.
Why does my script say 'Permission denied' when I run it?
A file needs the execute bit before the shell will run it directly. If ./script.sh fails with Permission denied, run chmod +x script.sh to add execute permission, then run it again. Files copied from Windows, downloaded, or extracted from some archives often arrive without the execute bit set.
Is chmod 777 safe to use?
Rarely. chmod 777 lets every user on the system read, write and execute the file, which is a security risk and is almost never actually required. If something does not work, diagnose the real owner and group with ls -l and fix ownership with chown or grant the narrowest permission that solves the problem, such as chmod 644 for a data file or chmod 755 for a program.
This is part of the Windows Now Linux section. Browse all Linux guides, or head back to the Windows Now home page.