Files & Permissions¶
Every file on a Linux system has an owner, a group, and a set of permissions that control who can read, write, or execute it. Getting permissions wrong is one of the most common sources of bugs — and security vulnerabilities — in shell scripting.
Learning Objectives¶
By the end of this section you will be able to:
- Create, copy, move, and delete files and directories safely
- Read and decode the permission string from
ls -la - Change permissions using symbolic (
chmod u+x) and numeric (chmod 755) notation - Understand the difference between
chownandchmod - Identify the seven file types on a Linux system
Creating and Managing Files¶
Creating Directories and Files¶
mkdir scripts # create a directory
mkdir -p projects/backup/logs # create nested directories in one shot
touch notes.txt # create an empty file
echo "hello" > greeting.txt # create a file with content
Copying Files¶
cp source.txt destination.txt # copy a file
cp -r source_dir/ dest_dir/ # copy a directory recursively
cp -i file.txt backup.txt # prompt before overwriting
cp -p file.txt backup.txt # preserve timestamps and permissions
cp overwrites silently
cp source.txt existing.txt silently destroys existing.txt. Use -i for interactive mode while you are learning — it asks before overwriting.
Moving and Renaming¶
mv old_name.txt new_name.txt # rename a file
mv file.txt ~/Documents/ # move a file to another directory
mv -i file.txt existing.txt # prompt before overwriting
mv within the same filesystem is instant
Moving a file on the same filesystem does not copy data — it just updates the directory entry. Moving across filesystems (e.g., to a USB drive) copies then deletes, which takes time proportional to file size.
Removing Files and Directories¶
rm file.txt # remove a file
rm -i file.txt # prompt before removing
rm -r directory/ # remove directory and all contents
rmdir empty_dir/ # remove an empty directory only
rm is permanent
There is no trash can on the command line. Once you run rm, the file is gone. Always double-check the path before running. Never run rm -rf / or rm -rf ~ — those destroy your entire system or home directory.
Add -i while learning
Put alias rm='rm -i' in your ~/.bashrc while you are learning. It adds a confirmation prompt before every deletion.
Understanding Permissions¶
Run ls -la in any directory:
total 20
drwxr-xr-x 2 user user 4096 Jan 15 09:10 .
drwxr-xr-x 8 user user 4096 Jan 15 09:10 ..
-rwxr-xr-x 1 user user 256 Jan 15 09:08 backup.sh
-rw-r--r-- 1 user user 128 Jan 15 09:05 config.txt
-rw------- 1 user user 64 Jan 15 09:03 secret.key
The first column is the permission string. Decoding -rwxr-xr-x:
- rwx r-x r-x
│ │ │ │
│ │ │ └─── Other (everyone else on the system)
│ │ └─────── Group (members of the file's group)
│ └─────────── User (the file's owner)
└───────────── File type
Each triplet uses three characters: r (read), w (write), x (execute). A dash - means that permission is not set.
| Triplet | Meaning |
|---|---|
rwx |
read + write + execute |
r-x |
read + execute, no write |
r-- |
read only |
--- |
no permissions at all |
File Types¶
The very first character of the permission string is the file type indicator:
| Char | Type | Example |
|---|---|---|
- |
Regular file | config.txt, script.sh |
d |
Directory | scripts/ |
l |
Symbolic link | link -> /path/to/target |
p |
Named pipe (FIFO) | Inter-process communication |
s |
Socket | Network communication |
c |
Character device | /dev/tty |
b |
Block device | /dev/sda |
Changing Permissions with chmod¶
Symbolic Mode¶
chmod u+x script.sh # add execute for the owner (user)
chmod g-w file.txt # remove write for the group
chmod o=r file.txt # set other to read-only (exactly, overwriting existing)
chmod a+r file.txt # add read for all three (user, group, other)
chmod u+x,g-w file.txt # multiple changes at once
Letters: u = user/owner, g = group, o = other, a = all three.
Operators: + = add permission, - = remove, = = set exactly.
Numeric (Octal) Mode¶
Each permission is a bit: r=4, w=2, x=1. Add them for each group:
| Octal | Binary | String |
|---|---|---|
7 |
111 |
rwx |
6 |
110 |
rw- |
5 |
101 |
r-x |
4 |
100 |
r-- |
0 |
000 |
--- |
chmod 755 script.sh # rwxr-xr-x — standard for scripts and directories
chmod 644 config.txt # rw-r--r-- — standard for config and data files
chmod 600 secret.key # rw------- — private files: only owner can read/write
chmod 700 private_dir/ # rwx------ — private directory
The two modes you will use 90% of the time
chmod 755 for any script or directory you want others to execute or traverse.
chmod 644 for any data or config file you want others to read but not modify.
Making a Script Executable¶
Without the execute bit, running ./script.sh gives:
Why ./?
./script.sh means "run script.sh from the current directory." Without ./, bash looks for script.sh in the directories listed in $PATH. Your current directory is intentionally not in $PATH for security reasons.
Changing Ownership with chown¶
chown alice file.txt # change owner to alice
chown alice:developers file.txt # change owner and group
chown -R alice:developers dir/ # recursive — entire directory tree
chown usually requires sudo
Changing file ownership is a privileged operation. You will typically need sudo chown ... unless you own both the source and target user accounts on the system.
Checking Who You Are¶
Common Mistakes¶
Forgetting -R on a directory
chmod 755 mydir changes the directory's permissions but not the files inside it. Use chmod -R 755 mydir/ to change the directory and everything under it recursively. Be careful — recursively setting x on files that should not be executable is a common mistake.
Setting permissions too broadly
chmod 777 gives everyone read, write, and execute access. This is almost never correct and can be a security issue on shared systems. Start from 644 or 755 and add permissions only as needed.
SSH key permissions
If your SSH private key (~/.ssh/id_rsa) has permissions wider than 600, SSH will refuse to use it and show: WARNING: UNPROTECTED PRIVATE KEY FILE!. Fix with chmod 600 ~/.ssh/id_rsa.
Practice Exercises¶
Warm-Up (run and observe)¶
- Run
ls -la /etc/. Find three files with different permission strings. Decode each one: what can the owner, group, and others do? - Create
~/practice/. Inside it, create three files:readme.txt,script.sh, anddata.csv. - Run
ls -la ~/practice/. Note that none of the three files are executable. - Run
chmod +x ~/practice/script.sh. Runls -la ~/practice/again. What changed in the permission string?
Main (write a short script)¶
Create ~/scripts/check_permissions.sh:
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-.}"
echo "=== Permissions in: $TARGET ==="
ls -la "$TARGET"
echo ""
echo "=== Writable files ==="
find "$TARGET" -maxdepth 1 -writable -type f
echo ""
echo "=== Executable files ==="
find "$TARGET" -maxdepth 1 -executable -type f
Run it:
chmod +x ~/scripts/check_permissions.sh
~/scripts/check_permissions.sh ~/scripts/
~/scripts/check_permissions.sh /etc/
Stretch¶
- Create
private.txt. Set permissions so only you can read and write it — no group, no other access. Verify withls -la. What numeric mode did you use? - What does
chmod 1777do? Where do you see this on most Linux systems? (Hint:ls -la /tmp.) - Read about
umaskinman bash. What is the defaultumaskon your system? How does it affect the permissions of newly created files?
Interview Questions¶
- What does
chmod 755mean in terms of who can do what?
Show answer
Owner (7 = rwx) can read, write, and execute. Group (5 = r-x) can read and execute but not write. Others (5 = r-x) can read and execute but not write. This is the standard for scripts and public directories.
- What is the difference between
chmodandchown?
Show answer
chmod changes the permission bits — who can read, write, or execute the file. chown changes the ownership — which user account and group the file belongs to. You typically need sudo for chown but not for chmod when modifying files you own.
- Why do scripts need the execute bit but plain text files do not?
Show answer
When you run ./script.sh, the kernel checks the execute bit before allowing execution. Plain text files are never directly executed by the kernel — they are just data. Note: bash script.sh works without the execute bit because bash is doing the executing; it only needs read permission on the file.
- What does
-rw-------mean, and when should you use it?
Show answer
Owner can read and write; group and others have no permissions at all (numeric: 600). Use this for private key files (~/.ssh/id_rsa), credential files, and anything containing secrets. SSH will actively refuse to use a private key with permissions more permissive than 600.
- What is the sticky bit, and where do you see it in practice?
Show answer
The sticky bit (chmod +t, shown as t in the x position for others, e.g., drwxrwxrwt) on a directory means only the file's owner or root can delete or rename files inside it — even if others have write permission to the directory. You see it on /tmp: everyone can create files there, but you can only delete your own.