Lesson 4 • Beginner
Permissions and Users 🔐
By the end of this lesson you'll be able to read any file's -rwxr-xr-x permission string at a glance, change permissions with chmod (both ways), reassign ownership with chown, use sudo safely, and turn a plain text file into a script you can actually run.
What You'll Learn
- Read the rwxr-xr-x string — user, group, and other, each with read/write/execute
- Convert between symbolic (rwx) and octal (755) permissions with confidence
- Change permissions with chmod — symbolic (u+x) and octal (644)
- Reassign file ownership with chown user:group
- Use sudo to run commands as root — and know why that's dangerous
- Make a script executable so the shell will actually run it
cd and ls. These are real shell commands — run them in your own terminal (macOS, Linux, or WSL on Windows). Each example lists the output you should expect to see.chmod is the locksmith that re-cuts those keys; chown changes whose name is on the door; and sudo is the master key — powerful, and the reason you don't carry it around loose.1️⃣ Reading the rwx Permission String
Run ls -l and every line begins with 10 characters like -rwxr-xr-x. The first character is the file type (- for a normal file, d for a directory). The remaining nine are three groups of three — user (the owner), group, and other (everyone else) — and within each group the three slots are always read, write, execute in that order. A letter means the permission is granted; a dash - means it isn't.
# 'ls -l' lists files in long format, starting with the permission string.
# Make two demo files and look at them.
touch notes.txt
mkdir reports
ls -l
# Read the 10 characters on the left of each line like this:
# -rwxr-xr-x
# |\__/\__/\__/
# | user group other
# type (- = file, d = directory, l = symlink)
#
# Each set of three is read / write / execute, in that order.
# A letter means "allowed", a dash (-) means "not allowed".total 4
-rw-r--r-- 1 alice alice 0 Jun 15 09:12 notes.txt
drwxr-xr-x 2 alice alice 4096 Jun 15 09:12 reportsnotes.txt is rw-r--r-- and the reports directory is drwxr-xr-x (the leading d marks a directory).Anatomy of -rwxr-xr--
-rwxr-xr-- ^^^^ ^^^ ^^^ | | | | | | | +-- Other: r-- (read only) | | +------ Group: r-x (read + execute) | +---------- User: rwx (read + write + execute) +------------ Type: - (a normal file)
| Permission | Letter | Octal | On a file | On a directory |
|---|---|---|---|---|
| Read | r | 4 | View contents | List its files |
| Write | w | 2 | Modify contents | Add/remove files |
| Execute | x | 1 | Run as a program | cd into it |
| None | - | 0 | No access | No access |
Octal notation just adds the values: rwx = 4+2+1 = 7, r-x = 4+0+1 = 5, r-- = 4+0+0 = 4. So -rwxr-xr-- is 754. Three digits, one per group — that's the whole trick.
2️⃣ Changing Permissions with chmod
chmod ("change mode") re-cuts the keys, and it works two ways. Symbolic mode adjusts one thing relative to what's there: chmod u+x file adds (+) execute (x) for the user (u); g is group, o is other, a is all. Octal mode sets all three groups at once to an exact value: chmod 644 file. Use symbolic for a quick tweak, octal to declare a known final state. Run the worked example and watch the string change with each command.
# Watch how each octal mode maps to the rwx string.
# 'stat -c %A %a %n' prints the symbolic string, the octal, and the name.
touch demo.sh
chmod 755 demo.sh && stat -c '%A %a %n' demo.sh # rwxr-xr-x
chmod 644 demo.sh && stat -c '%A %a %n' demo.sh # rw-r--r--
chmod 700 demo.sh && stat -c '%A %a %n' demo.sh # rwx------
chmod 600 demo.sh && stat -c '%A %a %n' demo.sh # rw-------
# Each digit is the sum of: read=4 write=2 execute=1
# 7 = 4+2+1 = rwx 5 = 4+0+1 = r-x 4 = 4+0+0 = r-- 0 = ---
# The three digits set user (owner), group, and other — in that order.-rwxr-xr-x 755 demo.sh
-rw-r--r-- 644 demo.sh
-rwx------ 700 demo.sh
-rw------- 600 demo.shchmod sets an exact mode and stat prints the resulting string.Now compute one yourself. The program below is almost complete — work out the three-digit octal for rwxr-xr-- using read=4, write=2, execute=1, then fill in the blank.
# 🎯 YOUR TURN — set a file to exactly rwxr-xr-- using octal mode.
#
# Work out each group from read=4 write=2 execute=1:
# user = rwx = 4+2+1 = ?
# group = r-x = 4+0+1 = ?
# other = r-- = 4+0+0 = ?
touch deploy.sh
# 👉 replace ___ with the three-digit octal number (no spaces)
chmod ___ deploy.sh
stat -c '%A %a %n' deploy.sh
# ✅ Expected output:
# -rwxr-xr-- 754 deploy.sh-rwxr-xr-- 754 deploy.sh___ with the octal number, run it in your terminal, and check the output matches 754.3️⃣ Making a Script Executable
When you create a script, it's just text — the execute bit is off, so the shell refuses to run it and you get Permission denied. The fix is one command: chmod u+x script.sh adds execute for the owner, and now ./script.sh works. This is one of the most common things you'll do on the command line, so it's worth doing by hand once.
# A fresh script is NOT executable, so the shell refuses to run it.
echo '#!/bin/bash' > hello.sh
echo 'echo "Hello!"' >> hello.sh
./hello.sh # try to run it -> fails (no execute bit)
# Add the execute bit for the owner with symbolic mode, then run it:
chmod u+x hello.sh # u = user/owner, +x = add execute
ls -l hello.sh # the owner's 'x' now shows
./hello.sh # now it runsbash: ./hello.sh: Permission denied
-rwxr--r-- 1 alice alice 31 Jun 15 09:14 hello.sh
Hello!./hello.sh fails, then after chmod u+x it prints Hello!.Your turn again. Make a script runnable for its owner, then lock down an SSH key the way SSH demands. Fill in the two blanks:
# 🎯 YOUR TURN — make a backup script runnable, then lock down an SSH key.
touch backup.sh
# 1) Add the execute bit for the OWNER ONLY, using symbolic mode.
# 👉 replace ___ with the symbolic flag (owner + add execute)
chmod ___ backup.sh
# 2) An SSH private key MUST be readable/writable by its owner ONLY (octal 600),
# or SSH refuses to use it. Set it with octal mode.
touch id_rsa
# 👉 replace ___ with the octal number for rw-------
chmod ___ id_rsa
stat -c '%A %n' backup.sh id_rsa
# ✅ Expected output:
# -rwxr--r-- backup.sh
# -rw------- id_rsa-rwxr--r-- backup.sh
-rw------- id_rsa___ blanks (one symbolic, one octal), run it, and compare against the expected output.4️⃣ Changing Ownership with chown
Permissions decide what each audience may do; ownership decides who the owner and group actually are. chown user file changes the owner, and chown user:group file changes both at once. Because reassigning ownership is a privileged action, it almost always needs sudo — you can't quietly hand your files to someone else, or grab theirs. Add -R to apply it through a whole directory tree.
# chown changes WHO owns a file. Changing ownership needs sudo
# (you can't give your files away, or take others', without admin rights).
ls -l report.csv # owned by root right now
sudo chown alice report.csv # change the owner to alice
sudo chown alice:devs report.csv # change owner AND group (owner:group)
sudo chown -R alice:devs project/ # -R = recurse into the directory
ls -l report.csv # owner and group have changed-rw-r--r-- 1 root root 512 Jun 15 09:15 report.csv
-rw-r--r-- 1 alice devs 512 Jun 15 09:15 report.csvreport.csv moves from root root to alice devs. (Substitute usernames/groups that exist on your machine.) Deep Dive: sudo and why root is dangerous
sudo ("superuser do") runs a single command as root — the all-powerful administrator account that ignores every permission check. You need it to install software, edit system files in /etc, or run chown. Root has no safety net: permissions exist partly to protect you from your own typos, and root removes that protection entirely. The classic disaster is a stray space in sudo rm -rf / some/path, which starts deleting the entire filesystem.
sudo apt install htop # install software (needs admin) sudo nano /etc/hosts # edit a protected system file sudo -i # open a full root shell (use sparingly!) whoami # who am I right now? -> alice sudo whoami # who would this run as? -> root
Rule of thumb: if a command works without sudo, don't add it. Use the least privilege that gets the job done, and never paste a sudo command you don't understand.
Knowing your own user and groups
Your group memberships decide which files' group permissions apply to you, so it helps to know who you are:
whoami # your username -> alice id # user id + every group -> uid=1000(alice) gid=1000(alice) groups=... groups # just the group names -> alice sudo devs
If you're in the sudo (or wheel) group, you're allowed to use sudo. If a file's group is devs and you're a member of devs, the file's group permissions apply to you.
Common Errors (and the fix)
bash: ./script.sh: Permission denied— the file isn't executable. Add the execute bit:chmod u+x script.sh(or+xfor everyone), then run it again.- Forgetting
+xafter editing a script — a brand-new or downloaded script has no execute bit by default. If it won't run, checkls -lfor thexbefore assuming the code is broken. - Over-using
chmod 777— making everything world-writable is a security hole and breaks tools that demand stricter modes. Grant the least access that works:644files,755scripts/folders,600secrets. chown: changing ownership of 'file': Operation not permitted— you tried to change ownership without admin rights. Prefix the command withsudo.Permissions 0644 for 'id_rsa' are too open— SSH refuses a private key that others can read. Lock it down:chmod 600 ~/.ssh/id_rsa.- A
sudofootgun: a stray space, as insudo rm -rf / home/old, can target/itself. Double-check the path before pressing Enter — root won't stop you.
📋 Quick Reference
| Octal | Symbolic | Sum | Typical use |
|---|---|---|---|
| 7 | rwx | 4+2+1 | Full access |
| 6 | rw- | 4+2 | Read & write, no run |
| 5 | r-x | 4+1 | Read & run, no edit |
| 4 | r-- | 4 | Read only |
| 644 | rw-r--r-- | — | Normal files |
| 755 | rwxr-xr-x | — | Scripts & folders |
| 600 | rw------- | — | Secrets, SSH keys |
| Command | What it does |
|---|---|
| ls -l | Show permissions, owner, and group |
| chmod 755 file | Set exact permissions (rwxr-xr-x) |
| chmod u+x file | Add execute for the owner |
| chmod -R 755 dir/ | Apply recursively to a directory |
| sudo chown user:grp file | Change owner and group |
| sudo command | Run a command as root |
| whoami / id / groups | Show your user and group membership |
Frequently Asked Questions
Q: What's the difference between symbolic and octal chmod?
They do the same job two ways. Symbolic mode (chmod u+x file) adds or removes one permission relative to what's already there — great for a quick tweak. Octal mode (chmod 755 file) sets all three groups at once to an exact value, so it doesn't matter what they were before. Use symbolic for small changes, octal to set a known final state.
Q: Why is my script giving 'Permission denied' when I run it?
The file almost certainly lacks the execute bit. Run ls -l yourscript.sh — if you don't see an x in the owner's group, run chmod u+x yourscript.sh (or chmod +x for everyone) and try again. Execute is what tells the shell a file is allowed to run.
Q: Why shouldn't I just chmod 777 everything to fix permission problems?
777 means every user on the system can read, write, AND execute the file — including modifying or replacing it. It's a security hole, and on things like SSH keys or web server files it can break the program entirely (SSH refuses keys that others can read). Grant the least access that works: 644 for normal files, 755 for scripts and folders, 600 for secrets.
Q: When do I actually need sudo?
Only for actions that touch the whole system or other users' files: installing software, editing files in /etc, changing ownership with chown, or writing outside your home directory. For your own files in your home folder you never need it. If a command works without sudo, don't add it — running as root removes the safety net that protects you from typos.
Q: What's the difference between user, group, and other?
Every file has one owner (user) and one owning group. 'User' permissions apply to the owner, 'group' permissions apply to anyone in the file's group, and 'other' permissions apply to everyone else on the system. That's why the rwx string has three sets — one rule for each audience.
Q: How do I see which user and groups I am?
Run whoami to print your username, id to see your user ID plus every group you belong to, and groups for just the group names. Your group memberships decide which files' 'group' permissions apply to you.
Mini-Challenge: ship a private deploy script
No blanks this time — just a brief and an outline to keep you on track. Write the commands yourself, run them in your terminal, and check your output against the example in the comments.
# 🎯 MINI-CHALLENGE: ship a private deploy script
# 1. Create a script file called release.sh
# 2. Make it executable by the OWNER ONLY, and readable by nobody else
# (hint: the octal for rwx------ ... user gets read+write+execute,
# group and other get nothing).
# 3. Print the permissions with: stat -c '%A %a %n' release.sh
#
# ✅ Expected output:
# -rwx------ 700 release.sh
# your commands here-rwx------ 700 release.sh.🎉 Lesson Complete!
- ✅ The
-rwxr-xr-xstring is type + user + group + other, each with read/write/execute - ✅ Octal adds
read=4, write=2, execute=1per group, sorwxr-xr--=754 - ✅
chmodchanges permissions — symbolic (u+x) for tweaks, octal (644/755) for exact modes - ✅
chown user:groupreassigns ownership (usually needssudo) - ✅
sudoruns as root — powerful, no safety net, use it sparingly - ✅ A script needs the execute bit (
chmod u+x) before the shell will run it - 🎓 You've finished the Command Line course! From navigation to processes to permissions, you can now work confidently in any terminal.
Sign up for free to track which lessons you've completed and get learning reminders.