Skip to main content
    Courses/Command Line/Permissions and Users

    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

    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.

    Worked example: read ls -l output
    # '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".
    Output
    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 reports
    Run this in your own terminal — notes.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)
    PermissionLetterOctalOn a fileOn a directory
    Readr4View contentsList its files
    Writew2Modify contentsAdd/remove files
    Executex1Run as a programcd into it
    None-0No accessNo 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.

    Worked example: octal modes map to the rwx string
    # 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.
    Output
    -rwxr-xr-x  755  demo.sh
    -rw-r--r--  644  demo.sh
    -rwx------  700  demo.sh
    -rw-------  600  demo.sh
    Run this in your own terminal — each chmod 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: compute the octal for rwxr-xr--
    # 🎯 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
    Output
    -rwxr-xr--  754  deploy.sh
    Replace ___ 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.

    Worked example: turn a text file into a runnable script
    # 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 runs
    Output
    bash: ./hello.sh: Permission denied
    -rwxr--r-- 1 alice alice 31 Jun 15 09:14 hello.sh
    Hello!
    Run this in your own terminal — the first ./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: chmod a script and an SSH key
    # 🎯 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
    Output
    -rwxr--r--  backup.sh
    -rw-------  id_rsa
    Fill in both ___ 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.

    Worked example: chown an owner and a group
    # 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
    Output
    -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.csv
    Run this in your own terminal — report.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 +x for everyone), then run it again.
    • Forgetting +x after editing a script — a brand-new or downloaded script has no execute bit by default. If it won't run, check ls -l for the x before 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: 644 files, 755 scripts/folders, 600 secrets.
    • chown: changing ownership of 'file': Operation not permitted — you tried to change ownership without admin rights. Prefix the command with sudo.
    • 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 sudo footgun: a stray space, as in sudo rm -rf / home/old, can target / itself. Double-check the path before pressing Enter — root won't stop you.

    📋 Quick Reference

    OctalSymbolicSumTypical use
    7rwx4+2+1Full access
    6rw-4+2Read & write, no run
    5r-x4+1Read & run, no edit
    4r--4Read only
    644rw-r--r--Normal files
    755rwxr-xr-xScripts & folders
    600rw-------Secrets, SSH keys
    CommandWhat it does
    ls -lShow permissions, owner, and group
    chmod 755 fileSet exact permissions (rwxr-xr-x)
    chmod u+x fileAdd execute for the owner
    chmod -R 755 dir/Apply recursively to a directory
    sudo chown user:grp fileChange owner and group
    sudo commandRun a command as root
    whoami / id / groupsShow 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: release.sh, owner-only
    # 🎯 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
    Write the commands yourself and run them in your terminal — aim for -rwx------ 700 release.sh.

    🎉 Lesson Complete!

    • ✅ The -rwxr-xr-x string is type + user + group + other, each with read/write/execute
    • ✅ Octal adds read=4, write=2, execute=1 per group, so rwxr-xr-- = 754
    • chmod changes permissions — symbolic (u+x) for tweaks, octal (644/755) for exact modes
    • chown user:group reassigns ownership (usually needs sudo)
    • sudo runs 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.

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service