Linux File Permissions Explained
Read every rwx string at a glance, change permissions with chmod (symbolic and numeric), change ownership with chown, and understand when to use sudo. With runnable examples.
What you'll learn
- ✓How to read the rwx permission string in ls -l output
- ✓The difference between owner, group, and other permissions
- ✓How to change permissions with chmod — symbolic and numeric forms
- ✓How to change ownership with chown and chgrp
- ✓When and how to use sudo safely
- ✓Common permission mistakes and how to recover from them
Prerequisites
- •Read Understanding the Linux File System first
- •A working shell on Ubuntu/Debian, WSL, or macOS
Every file and directory on Linux belongs to exactly one user and one group, and has a permission string that says who is allowed to read it, write to it, or execute it. Once you can read those strings fluently, half of the mystery around chmod 755, “permission denied,” and “why does my script not run?” disappears.
This post explains the model, then the two commands you change it with: chmod for permissions and chown for ownership.
Reading ls -l output
Make a practice file and look at its long listing:
cd ~ && mkdir -p perms-practice && cd perms-practice
echo "hello" > note.txt
ls -l note.txt
The output looks something like:
-rw-r--r-- 1 yash yash 6 Jun 14 10:32 note.txt
Every column carries meaning:
-— file type (-regular file,ddirectory,lsymlink, etc.)rw-r--r--— the permission string (the focus of this post)1— number of hard links (mostly ignore)yash— owner (user)yash— group6— size in bytesJun 14 10:32— last modified timenote.txt— name
The permission string is what we care about.
The permission string, decoded
The nine characters after the type are three groups of three:
rw- r-- r--
│ │ │
│ │ └── other (everyone else)
│ └────── group
└────────── owner (user)
Within each group:
r— read permissionw— write permissionx— execute permission (or, for a directory, “enter”)-— that permission is not granted
So -rw-r--r-- means:
- This is a regular file.
- The owner can read and write it, but not execute it.
- The group can only read it.
- Other (everyone else on the system) can only read it.
This is the default for new files on most systems. It is sensible: only you can edit, but anyone could read if they could see it.
For directories, the meanings are slightly different:
r— list the directory’s contentsw— create, delete, or rename entries in the directoryx— enter the directory (i.e.,cdinto it or use it as part of a path)
A directory you can r but not x is almost useless — you cannot cd into it.
A second example: an executable script
Create a tiny script and look at its permissions:
cat > greet.sh <<'EOF'
#!/bin/bash
echo "hello from the script"
EOF
ls -l greet.sh
You will see something like -rw-r--r--. Try to run it:
./greet.sh
# bash: ./greet.sh: Permission denied
The file is readable but not executable. Fix that:
chmod +x greet.sh
ls -l greet.sh
./greet.sh
Now the listing shows -rwxr-xr-x and the script runs. You just used chmod in its simplest form.
Changing permissions with chmod
chmod (change mode) has two syntaxes: symbolic (human-friendly) and numeric (compact). Both produce the same result. Pick whichever clicks for you — most people end up using both.
Symbolic form
The pattern is chmod [who][operation][what] file.
- who —
u(user/owner),g(group),o(other),a(all) - operation —
+(add),-(remove),=(set exactly) - what —
r,w,x
Examples:
chmod +x script.sh # add execute for everyone who can already see it
chmod u+x script.sh # add execute for the owner only
chmod g-w shared.txt # remove write from group
chmod o=r public.txt # set other to exactly "read" (clear w, x)
chmod a+r notes.md # all (user, group, other) can read
chmod u=rw,go=r config.yml # set multiple groups at once
The symbolic form is great when you want to change one bit without thinking about the others. It does not overwrite the permissions you did not mention.
Numeric (octal) form
Each permission group is encoded as a single digit from 0 to 7. The bits are:
r= 4w= 2x= 1
You sum the bits for each group, then write three digits — owner, group, other.
| Digit | Permissions |
|---|---|
| 7 | rwx |
| 6 | rw- |
| 5 | r-x |
| 4 | r— |
| 3 | -wx |
| 2 | -w- |
| 1 | —x |
| 0 | --- |
So:
chmod 644 note.txt # rw-r--r-- (default for files)
chmod 755 script.sh # rwxr-xr-x (default for executables)
chmod 700 secret.key # rwx------ (only you, full access)
chmod 600 ~/.ssh/id_rsa # rw------- (private key — required)
chmod 777 anything # rwxrwxrwx (almost never appropriate)
644 and 755 are the two values you will type most often by far. 644 for “a normal file” and 755 for “an executable file or a directory.”
chmod 755 ~/scripts # directory you and others should be able to enter
chmod 700 ~/.ssh # private SSH directory
Try it yourself. Inside ~/perms-practice, create three files: public.txt, team.txt, secret.txt. Use chmod to set them to 644, 640, and 600 respectively. Then run ls -l and read the resulting permission strings out loud, translating each rwx triplet back to the digit. Repeat until it is automatic.
Changing ownership with chown and chgrp
Two related commands change who a file belongs to, rather than what they can do with it.
sudo chown alice file.txt # change the owner to alice
sudo chown alice:developers file.txt # change owner AND group
sudo chgrp developers file.txt # change only the group
sudo chown -R alice:developers /srv/app # recursive — whole directory tree
chown almost always requires sudo, because giving away ownership of a file you own is a privileged operation on most systems. On macOS the syntax is identical.
The recursive -R flag is essential when you copy a directory to a server and need every file inside it to belong to the right user — a common deployment step.
When and how to use sudo
You will hit “Permission denied” the moment you try to edit a file in /etc or install a package. The fix is sudo:
nano /etc/hosts # Permission denied
sudo nano /etc/hosts # works — runs nano as root
sudo apt update # update package index (requires root)
sudo (“substitute user, do”) temporarily runs a single command as another user, defaulting to root. It will prompt for your password the first time and then remember you for a few minutes.
Some habits worth forming early:
- Read the command before you press Enter. Anything after
sudoruns with full system privileges. There is no undo. - Avoid
sudo suandsudo -iunless you really need a root shell. Running one command at a time withsudois safer because the privilege expires. - Never
chmod 777something to “make permissions go away.” It is almost always the wrong fix and is a common cause of security issues. - Do not
sudoyour editor for files in your own home directory. If a file in~/is unwritable, the right fix is usuallychownto give it back to you, notsudo nano.
macOS does not have a root user enabled by default, but sudo works the same way — your account password is used.
The execute bit on directories, one more time
The single most common point of confusion: a directory’s x bit means “you can enter this directory”, not “you can run it as a program.”
mkdir secret
chmod 600 secret # rw- but no x
ls secret
# ls: cannot open directory 'secret': Permission denied
cd secret
# bash: cd: secret: Permission denied
Even though r is set, without x you cannot use the directory. For directories, the common safe values are:
755— anyone can list and enter (typical for shared folders)750— only owner and group can list and enter700— only owner can list or enter (good for~/.ssh)
A few real-world recipes
Make a script executable so you can run it directly:
chmod +x deploy.sh
Lock down an SSH private key (required by ssh):
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh
If the permissions on a private key are too open, ssh will refuse to use it.
Recursively fix a directory you cloned with the wrong owner:
sudo chown -R yash:yash ~/projects/myapp
Give your group write access to a shared folder:
sudo chgrp developers /srv/shared
sudo chmod 775 /srv/shared
Find files with overly permissive modes:
find ~ -type f -perm -o=w # files world-writable
find ~ -type f -perm 777 # files with rwxrwxrwx
Common mistakes and how to recover
“I ran chmod -R 777 on my project to make a build error go away.”
This is rarely the cause and almost always creates a security problem. Restore reasonable defaults with:
find ~/projects/myapp -type d -exec chmod 755 {} \;
find ~/projects/myapp -type f -exec chmod 644 {} \;
chmod +x ~/projects/myapp/scripts/*.sh # restore executables
“I chowned a file to root and now I cannot edit it.”
Take it back:
sudo chown yash:yash mistake.txt
“Why does my script say ‘command not found’ even with chmod +x?”
You probably ran script.sh instead of ./script.sh. The shell only searches PATH by name — to run a file in the current directory, prefix it with ./. The file also needs a shebang line (#!/bin/bash as the first line) so the kernel knows what interpreter to use.
Try it yourself. Inside ~/perms-practice, create a script hello.sh containing #!/bin/bash and echo hi. Try running it three ways: hello.sh (will not work — not on PATH), ./hello.sh (will not work yet — not executable), and finally after chmod +x hello.sh, ./hello.sh again. Walk through why each step does what it does.
Recap
You now know:
ls -lshows file type, then three rwx triplets for owner, group, other- For directories,
xmeans “can enter,”rmeans “can list contents” chmodchanges permissions in symbolic (u+x,go=r) or numeric (644,755,700) formchownchanges ownership;chgrpchanges only the group; both usually needsudosudoruns the next command as root — read commands before pressing Enterchmod 777is almost never the right answer;644and755are the everyday defaults- SSH keys must be
600and their directory700orsshwill refuse to use them
You now have the full beginner toolkit: what Linux is, how to use a terminal, the essential commands, the file system layout, and the permission model. With these five posts behind you, almost any command-line documentation you read for the next year will make sense.
Next steps
A natural follow-on is package management — apt on Ubuntu/Debian, brew on macOS — and from there shell scripting, SSH, and systemd. We will pick up that thread in the next series.
→ Next: Managing Software with apt and Homebrew
Questions or feedback? Email codeloomdevv@gmail.com.