Caractacus Hub

A Comprehensive Reference — 200+ Commands

Ubuntu Terminal
Handbook

Core bash, system administration, and scripting — Ubuntu 22.04 & 24.04 LTS, Bash 5.x

25 Sections 200+ Commands Bash 5.x Ubuntu 22.04 / 24.04 LTS June 2026

Contents — 25 Sections

ICore Operations

1. Getting Help & Navigation

Discovery and navigation tools — how to find out what a command does and move around the file system without leaving the shell.

man
The manual pager. Every installed command and most config files have a man page — the first place to look before searching online.
Examples
man ls
man 5 passwd          # section 5: file formats
man -k network        # same as apropos
man -f printf         # same as whatis

Key flags: -k (keyword search), section numbers 1–8 disambiguate commands from config files and syscalls

--help
Almost every GNU/Linux tool accepts --help for a quick option summary, faster than a full man page.
Examples
ls --help
tar --help | less
systemctl --help
apropos / whatis
Searches man page names and one-line descriptions for a keyword — useful when you know what you want to do but not the command name.
Examples
apropos copy
apropos "list directory"
whatis ls
whatis -a printf
info
GNU's hypertext-style documentation, more detailed than man pages for core utilities and bash itself.
Examples
info coreutils
info bash
info gcc
type / which / whereis
Locates a command and tells you whether it is a builtin, alias, function, or external binary.
Examples
type cd                # cd is a shell builtin
which python3          # /usr/bin/python3
whereis gcc             # binary, source and man page paths

Key flags: type is the most reliable since it understands aliases and functions; which only finds binaries on PATH

pwd
Prints the full path of the current working directory.
Examples
pwd
pwd -P    # resolve symlinks to the real path
cd
Changes the current directory. A handful of special arguments are used constantly.
Examples
cd /var/log
cd ~          # home directory
cd -          # previous directory
cd ..         # parent directory
cd            # no args also goes home
pushd / popd / dirs
Maintains a stack of directories so you can jump around and return without retyping paths.
Examples
pushd /etc/nginx
# ...do work...
popd          # back to where you started
dirs -v       # view the stack
history
Lists previously run commands. Combined with !! and Ctrl+R it is one of the biggest time-savers in the shell.
Examples
history | tail -20
!!              # re-run the last command
sudo !!         # re-run last command with sudo
!423            # re-run history entry 423

Key flags: Ctrl+R starts a reverse incremental search through history

2. File System Operations

Creating, copying, moving, and inspecting files and directories — the bread and butter of working in a terminal.

CommandCommon flagsDescription
ls-la -lh -lt -RLists files and directories
cp-r -p -v -aCopies files and directories
mv-v -nMoves or renames files and directories
rm-r -f -v -iDeletes files and directories
mkdir-p -vCreates directories
rmdirRemoves empty directories
touch-tCreates empty files or updates timestamps
ln-sCreates hard or symbolic links
statShows detailed file metadata
fileIdentifies file type by content, not extension
ls — common patterns
Lists directory contents. The single most-used command in any terminal session.
Examples
ls -la              # all files including hidden, long format
ls -lh              # human-readable sizes (K/M/G)
ls -lt              # sort by modification time, newest first
ls -R               # recurse into subdirectories
ls -d */            # list only directories
find
Searches a directory tree by name, type, size, age, or permissions, and can run a command on every match. The terminal's most powerful search tool.
Syntax
find <path> [-name|-iname <pattern>] [-type f|d] [-mtime <n>] [-size <n>] [-exec <cmd> {} \;]
Examples
find . -name "*.log"
find /var -type f -mtime -1          # modified in the last day
find . -type f -size +100M
find . -name "*.tmp" -delete
find . -name "*.sh" -exec chmod +x {} \;

Key flags: -iname (case-insensitive), -maxdepth (limit recursion), -mtime -n / +n (newer/older than n days)

cp / mv
Copy and move files and directories.
Examples
cp -r ~/project /backup/
cp -a src/ dest/          # archive mode: preserves permissions, timestamps, symlinks
mv old-name.txt new-name.txt
mv *.jpg ~/Pictures/
rm
Deletes files and directories. There is no Recycle Bin in the terminal — deleted means gone.
Examples
rm file.txt
rm -r old-folder/
rm -i *.tmp          # prompt before each deletion
WARNINGrm -rf is irreversible and will not ask for confirmation. Double-check the path before pressing enter, especially with wildcards or as root.
mkdir -p
Creates directories, including any missing parent directories in one go.
Examples
mkdir new-folder
mkdir -p projects/2026/website/assets   # creates the whole chain
ln
Creates links between files. A hard link is a second name for the same data; a symbolic link is a pointer to a path.
Examples
ln -s /opt/app/current /usr/local/bin/app   # symlink
ln original.txt hardlink.txt                 # hard link

Key flags: Symlinks can cross filesystems and point to directories; hard links cannot

du / df
Reports disk usage. du measures specific files or directories; df reports free space per mounted filesystem.
Examples
du -sh ~/Downloads          # total size of a folder
du -h --max-depth=1 /var   # one level of subfolders
df -h                      # free space on all mounts
stat / file
Inspects a file's metadata or identifies its actual type regardless of extension.
Examples
stat report.pdf
file mystery-file          # e.g. "ELF 64-bit LSB executable"

3. Text & File Content

Reading, searching, and transforming text — whether that's a config file, a CSV, or a live log stream.

cat / less / more
Display file content. cat dumps the whole file; less pages through it interactively (preferred for anything long).
Examples
cat notes.txt
cat file1.txt file2.txt > combined.txt
less /var/log/syslog          # q to quit, / to search
head / tail
Show the first or last lines of a file. tail -f follows a growing file live — the standard way to watch a log in real time.
Examples
head -20 access.log
tail -50 access.log
tail -f /var/log/nginx/error.log     # live follow, Ctrl+C to stop
tail -n +100 file.txt                # everything from line 100 onward
grep
Searches for text patterns, including regular expressions, within files or piped input. The terminal's find-in-text tool.
Syntax
grep [-i -v -r -n -c -E] '<pattern>' <file>
Examples
grep -i "error" app.log
grep -rn "TODO" ./src
grep -v "^#" config.conf       # exclude commented lines
grep -E "warn|error" app.log    # extended regex, multiple patterns
grep -c "404" access.log        # count matching lines

Key flags: -i case-insensitive, -r recursive, -v invert match, -n show line numbers, -E extended regex

sed
Stream editor for find-and-replace and other line-based text transformations, without opening an editor.
Examples
sed 's/old/new/' file.txt              # replace first match per line
sed 's/old/new/g' file.txt             # replace all matches per line
sed -i 's/foo/bar/g' file.txt          # edit the file in place
sed -n '10,20p' file.txt               # print only lines 10-20

Key flags: -i edit in place (use -i.bak to keep a backup), -n with p suppresses default output

awk
A pattern-scanning and text-processing language, most often used for pulling out columns from structured text.
Examples
awk '{print $1}' access.log          # first column
ps aux | awk '{print $2, $11}'       # PID and command
awk -F',' '{print $2}' data.csv      # custom field separator
awk '$3 > 100 {print}' report.txt    # conditional print
sort / uniq
Sort lines and remove or count duplicates. Commonly chained together.
Examples
sort names.txt
sort -n numbers.txt              # numeric sort
sort -r file.txt                 # reverse order
sort file.txt | uniq             # remove duplicate lines
sort file.txt | uniq -c | sort -rn   # count and rank occurrences
cut / tr / wc
Extract columns, translate characters, and count lines/words/characters.
Examples
cut -d',' -f2 data.csv        # second comma-separated field
echo "hello" | tr 'a-z' 'A-Z'  # uppercase
wc -l file.txt                # line count
wc -w file.txt                # word count
diff
Compares two files line by line and shows the differences.
Examples
diff old.conf new.conf
diff -u old.conf new.conf     # unified diff, the format used by patches

4. Process Management

Inspecting, controlling, and managing the lifecycle of running processes — foreground, background, and persistent.

ps
Snapshot of currently running processes.
Examples
ps aux                       # everyone's processes, full detail
ps aux | grep nginx
ps -ef --forest              # tree view showing parent/child relationships

Key flags: aux (BSD style, most common), -ef (UNIX style)

top / htop
Live, continuously updating view of running processes and resource usage. htop is a friendlier, colour version (install with apt if not present).
Examples
top
htop
top -o %MEM        # sort by memory usage

Key flags: Inside top: q quit, k kill a process, M sort by memory, P sort by CPU

kill / killall / pkill
Sends a signal to a process, most commonly to terminate it.
Examples
kill 1234                  # graceful SIGTERM
kill -9 1234                # force kill, SIGKILL
killall firefox             # kill by name
pkill -f "python script.py" # kill by matching the full command line

Key flags: Try a plain kill first; reach for -9 only when the process won't respond

Background jobs — &, jobs, fg, bg
Run commands in the background while keeping the shell interactive, and move them between foreground and background.
Examples
long-task.sh &        # start in background
jobs                  # list background jobs
fg %1                 # bring job 1 to the foreground
bg %1                 # resume job 1 in the background
Ctrl+Z                # suspend the foreground job
nohup / disown
Keeps a background process alive after the terminal session closes.
Examples
nohup ./long-task.sh &
disown -h %1          # detach an already-running job from the shell

Key flags: nohup redirects output to nohup.out by default; combine with > to redirect elsewhere

nice / renice
Sets or adjusts a process's scheduling priority (-20 highest, 19 lowest).
Examples
nice -n 10 ./batch-job.sh
renice -n 5 -p 1234
lsof
Lists open files, including network sockets — useful for finding what process is holding a port or a file.
Examples
lsof -i :8080          # what's using port 8080
lsof /var/log/syslog   # what has this file open
pgrep / pidof
Finds process IDs by name without piping ps through grep.
Examples
pgrep nginx
pidof sshd

5. Service Management

Controlling systemd services — the standard init system on Ubuntu since 15.04.

ActionCommand
Check statussystemctl status nginx
Startsudo systemctl start nginx
Stopsudo systemctl stop nginx
Restartsudo systemctl restart nginx
Reload config without restartsudo systemctl reload nginx
Enable at bootsudo systemctl enable nginx
Disable at bootsudo systemctl disable nginx
Check if activesystemctl is-active nginx
Check if enabledsystemctl is-enabled nginx
systemctl list-units
Lists units (services, sockets, timers) and their current state — the quickest way to find what's running or what's failed.
Examples
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=failed
systemctl --failed
systemctl daemon-reload
Reloads systemd's unit definitions after editing a .service file. Required before changes take effect.
Examples
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
service (legacy)
Older SysV-style wrapper, still present on Ubuntu for compatibility. systemctl is preferred on any modern Ubuntu release.
Examples
sudo service nginx restart
Use journalctl -u <service> to see a service's logs — covered in Section 18, Logging & Journald.
IISystem & Users

6. System Information

Hardware, OS, and kernel information — the equivalent of opening Task Manager and System Properties combined.

uname
Prints system information — kernel name, version, and architecture.
Examples
uname -a          # everything
uname -r          # kernel release only
uname -m          # architecture (x86_64, aarch64...)
hostnamectl
Shows and sets the system hostname along with OS, kernel, and virtualization details.
Examples
hostnamectl
sudo hostnamectl set-hostname new-name
/etc/os-release / lsb_release
Identifies the exact Ubuntu version and codename.
Examples
cat /etc/os-release
lsb_release -a
lscpu / nproc
CPU architecture details and core count.
Examples
lscpu
nproc          # number of available processing units
free
Shows memory and swap usage.
Examples
free -h          # human-readable
watch -n 1 free -h   # refresh every second
lsblk / df -h
Lists block devices and partitions, and free space on mounted filesystems.
Examples
lsblk
lsblk -f          # include filesystem type and UUID
df -h
lsusb / lspci
Lists connected USB and PCI hardware.
Examples
lsusb
lspci
lspci -k          # show which kernel driver each device uses
uptime / vmstat
Quick health snapshot: how long the system has been up, load average, and virtual memory stats.
Examples
uptime
vmstat 1 5         # 5 samples, 1 second apart
dmesg
Shows kernel ring buffer messages — the first place to check for hardware or driver issues.
Examples
dmesg | tail -50
dmesg -T | grep -i usb     # human-readable timestamps

7. User & Group Management

Creating, modifying, and inspecting local user accounts and groups on a standalone Ubuntu machine.

Creating a user
adduser is the friendlier, interactive Debian/Ubuntu wrapper; useradd is the lower-level, scriptable version.
Examples
sudo adduser jdoe                       # interactive, prompts for password and details
sudo useradd -m -s /bin/bash jdoe       # -m creates home dir, -s sets shell
passwd
Sets or changes a user's password.
Examples
passwd                # change your own password
sudo passwd jdoe      # set another user's password
sudo passwd -l jdoe   # lock the account
sudo passwd -u jdoe   # unlock it
usermod
Modifies an existing user account.
Examples
sudo usermod -aG sudo jdoe          # add to a group (note -a, otherwise existing groups are wiped)
sudo usermod -L jdoe                 # lock account
sudo usermod -s /bin/zsh jdoe        # change default shell

Key flags: Always use -aG not -G alone — -G without -a replaces all existing group memberships

userdel / deluser
Removes a user account.
Examples
sudo deluser jdoe
sudo deluser --remove-home jdoe     # also delete their home directory
groupadd / groupdel / gpasswd
Manages groups.
Examples
sudo groupadd developers
sudo gpasswd -a jdoe developers     # add user to group
sudo gpasswd -d jdoe developers     # remove user from group
id / groups
Shows a user's UID, GID, and group memberships.
Examples
id
id jdoe
groups jdoe
who / w / last
Shows who is currently logged in and recent login history.
Examples
who
w               # who, plus what they're running
last -10        # last 10 login sessions
su / sudo
su switches users entirely; sudo runs a single command with elevated privileges, logging the action.
Examples
su - jdoe              # switch user with their full login environment
sudo apt update
sudo -i                # root shell with root's environment
sudo -u jdoe whoami    # run a command as a specific user
chage
Views or sets password expiry policy for an account.
Examples
sudo chage -l jdoe              # list current ageing settings
sudo chage -M 90 jdoe           # force password change every 90 days

8. Network Commands

Testing connectivity, inspecting interfaces, querying DNS, and transferring data over the network.

ping
Tests basic reachability of a host using ICMP echo requests.
Examples
ping google.com
ping -c 4 192.168.1.1     # stop after 4 packets
ip
The modern tool for viewing and configuring network interfaces, addresses, and routes — replaces the deprecated ifconfig and route.
Examples
ip addr show              # all interfaces and their IPs (or 'ip a')
ip route show              # routing table, including default gateway
ip link set eth0 up        # bring an interface up
ip -s link                 # interface statistics
ss
Shows socket statistics — the modern, faster replacement for netstat.
Examples
ss -tulpn                 # all listening TCP/UDP sockets with process names
ss -t state established   # established TCP connections only

Key flags: -t TCP, -u UDP, -l listening, -p show process, -n numeric (skip DNS lookups)

curl
Transfers data to or from a URL — HTTP requests, downloads, and API testing.
Examples
curl https://example.com
curl -O https://example.com/file.zip      # save with the remote filename
curl -I https://example.com               # headers only
curl -X POST -d '{"key":"val"}' -H "Content-Type: application/json" https://api.example.com
wget
Downloads files over HTTP/HTTPS/FTP, with good support for resuming and recursive fetches.
Examples
wget https://example.com/file.iso
wget -c https://example.com/big-file.zip    # resume a partial download
dig / nslookup / host
Queries DNS records.
Examples
dig example.com
dig example.com MX
dig +short example.com         # just the answer, no preamble
host example.com
traceroute / mtr
Shows the network path to a destination, hop by hop. mtr combines ping and traceroute into a live updating view.
Examples
traceroute google.com
mtr google.com          # interactive, q to quit
nc (netcat)
The networking Swiss Army knife — opens raw TCP/UDP connections, useful for quick port tests and small file transfers.
Examples
nc -zv example.com 443     # test if a port is open
nc -l 9000                  # listen on a port
hostname -I
Quickly shows the machine's own IP address(es) without parsing ip addr output.
Examples
hostname -I
IIIData & Types

9. Permissions & Ownership

Linux's permission model and ownership tools — who can read, write, or run what.

SymbolPermissionMeaning on a fileMeaning on a directory
rRead (4)View file contentsList directory contents
wWrite (2)Modify or delete file contentsAdd or remove files inside it
xExecute (1)Run the file as a program/scriptEnter (cd into) the directory
chmod
Changes a file or directory's permission bits, either symbolically or with octal numbers.
Syntax
chmod [ugoa][+-=][rwx] <file>   |   chmod <octal> <file>
Examples
chmod +x script.sh                # add execute for everyone
chmod 755 script.sh               # rwxr-xr-x
chmod 644 config.txt              # rw-r--r--
chmod -R 755 ./website/           # recursively
chmod u+w,g-w file.txt            # symbolic: user write on, group write off

Key flags: Octal digits: read 4, write 2, execute 1 — sum them per owner/group/other (e.g. 7=rwx, 5=r-x, 4=r--)

chown / chgrp
Changes file ownership (user and/or group).
Examples
sudo chown jdoe file.txt
sudo chown jdoe:developers file.txt     # user and group together
sudo chown -R www-data:www-data /var/www/html
sudo chgrp developers file.txt
umask
Sets the default permission mask applied to newly created files and directories.
Examples
umask              # show current mask, e.g. 0022
umask 077          # new files private to the owner only

Key flags: The mask is subtracted from the system default (666 for files, 777 for directories)

getfacl / setfacl
Manages Access Control Lists for permissions beyond the standard owner/group/other model — granting a specific extra user access without changing ownership.
Examples
getfacl file.txt
setfacl -m u:jdoe:rw file.txt     # grant jdoe read/write
setfacl -x u:jdoe file.txt        # remove that entry
The sticky bit (chmod +t, seen as t in /tmp's permissions) means only a file's owner can delete it, even if others can write to the containing directory. SUID/SGID (chmod u+s / g+s) make a program run with the file owner's/group's privileges rather than the caller's — powerful, and a common attack surface if misused.

10. Variables & Data Types

Storing and working with data in the shell — scalar variables, arrays, and bash's special built-in variables.

Variable basics
Bash variables are untyped by default and assigned with no spaces around the equals sign.
Examples
name="Alice"
count=42
echo "Hello, $name"
export PATH="$PATH:/opt/tool/bin"   # make visible to child processes
readonly API_KEY="abc123"           # cannot be changed after this
unset name

Key flags: export makes a variable available to subprocesses; without it, it's local to the current shell only

Special variables
Bash provides several automatic variables inside scripts and the interactive shell.
Examples
$0          # script name
$1 $2 ...   # positional arguments
$#          # number of arguments
$@          # all arguments as separate words
$?          # exit status of the last command
$$          # current process ID
$RANDOM     # a random integer
Arrays
Indexed arrays store an ordered list of values.
Examples
fruits=(apple banana cherry)
echo ${fruits[0]}          # apple
echo ${fruits[@]}          # all elements
echo ${#fruits[@]}         # array length, 3
fruits+=(date)              # append an element
for f in "${fruits[@]}"; do echo "$f"; done
Associative arrays
Key/value maps, declared explicitly with -A (bash 4+).
Examples
declare -A config
config[host]="db01"
config[port]=5432
echo ${config[host]}
for key in "${!config[@]}"; do echo "$key: ${config[$key]}"; done
Arithmetic context
Bash performs integer arithmetic inside double parentheses without needing expr for most cases.
Examples
count=5
(( count++ ))
(( total = count * 10 ))
if (( count > 3 )); then echo "big"; fi

11. String Manipulation

Bash's built-in parameter expansion syntax for trimming, replacing, and reformatting strings without external tools.

OperationSyntax / exampleNotes
Length${#var}Number of characters
Substring${var:5:3}Offset 5, length 3
Remove prefix${var#pattern}Shortest match; ## for longest
Remove suffix${var%pattern}Shortest match; %% for longest
Replace first match${var/find/replace}Case-sensitive
Replace all matches${var//find/replace}Global
Default value${var:-default}Use 'default' only if var is unset/empty
Uppercase${var^^}Lowercase: ${var,,}
Default if unset${var:=default}Also assigns the default to var
Practical examples
Common real-world string manipulation patterns combining the above.
Examples
path="/home/conor/report.txt"
echo ${path##*/}              # report.txt &mdash; strip everything up to the last slash
echo ${path%.*}               # /home/conor/report &mdash; strip the extension
name="Conor"
echo "Hello, ${name^^}!"     # Hello, CONOR!
Here-strings and printf
Quick ways to feed a literal string to a command, and to format output precisely.
Examples
grep "error" <<< "$log_line"
printf "%-10s %5d\n" "Name:" 42
printf "%s\n" "${fruits[@]}"     # one per line
For anything beyond simple substitution, reach for sed or awk (covered in Section 3) rather than fighting with nested parameter expansions.

12. Pipelines & Filtering

Chaining small commands into pipelines — the core idiom that makes the shell more powerful than any single tool.

The pipe |
Sends the output of one command directly into the input of the next, the foundation of composing small tools into bigger ones.
Examples
ps aux | grep nginx | awk '{print $2}'
cat access.log | grep "404" | wc -l
xargs
Builds and runs commands from piped input, useful when a command doesn't read stdin directly (like rm or cp).
Examples
find . -name "*.tmp" | xargs rm
find . -name "*.log" | xargs -I{} mv {} ./archive/
echo "file1 file2" | xargs -n1 echo    # one arg at a time

Key flags: -I{} lets you place the input anywhere in the command, not just at the end

tee
Writes pipeline output to a file while still passing it through to the next command — useful for logging while watching live output.
Examples
long-task.sh | tee output.log
echo "new line" | sudo tee -a /etc/some.conf   # -a appends, sudo with tee for protected files
Command substitution
Captures the output of a command into a variable or another command, with $(...) preferred over the older backtick syntax.
Examples
today=$(date +%Y-%m-%d)
files=$(ls *.txt | wc -l)
echo "There are $(nproc) CPU cores"
Process substitution
Treats the output of a command as if it were a file, useful when a command expects a filename rather than piped input.
Examples
diff <(sort file1.txt) <(sort file2.txt)
comm <(ls dirA) <(ls dirB)
comm / paste
Compares two sorted files line by line (comm), or merges lines from multiple files side by side (paste).
Examples
comm <(sort a.txt) <(sort b.txt)      # 3 columns: only in a, only in b, in both
paste names.txt scores.txt           # tab-joined columns
IVScripting

13. Loops & Conditionals

Branching and repeating logic in shell scripts — the building blocks of any automation.

if / elif / else
Conditional branching using test ([ ]) or the more modern [[ ]].
Examples
if [[ $count -gt 10 ]]; then
  echo "big"
elif [[ $count -gt 5 ]]; then
  echo "medium"
else
  echo "small"
fi

Key flags: Comparisons: -eq -ne -gt -lt -ge -le (numbers), == != (strings, inside [[ ]]), -z (empty string), -f -d (file/directory exists)

Prefer [[ ]] over [ ] in bash scripts — it supports &&/|| inside the brackets, pattern matching, and doesn't require quoting variables to avoid word-splitting bugs.
case
Pattern-matching alternative to a long if/elif chain.
Examples
case "$1" in
  start) echo "Starting..." ;;
  stop)  echo "Stopping..." ;;
  *.log) echo "A log file" ;;
  *)     echo "Unknown option" ;;
esac
for
Iterates over a list, a range, or a glob.
Examples
for f in *.txt; do echo "$f"; done
for i in {1..10}; do echo $i; done
for ((i=0; i<5; i++)); do echo $i; done    # C-style
while / until
Loops while a condition is true (while) or until it becomes true (until).
Examples
i=0
while (( i < 5 )); do
  echo $i
  (( i++ ))
done
until ping -c1 server01 &>/dev/null; do sleep 2; done    # poll until reachable
break / continue
Exit a loop early, or skip to the next iteration.
Examples
for i in {1..10}; do
  [[ $i -eq 5 ]] && break
  [[ $((i % 2)) -eq 0 ]] && continue
  echo $i
done

14. Functions & Scripts

Writing reusable functions and standalone scripts — turning one-off commands into repeatable tools.

function
Defines a reusable block of commands, with either the function keyword or just parentheses.
Examples
greet() {
  local name="${1:-World}"
  echo "Hello, $name!"
}
greet Alice

function cleanup {
  rm -rf /tmp/build-cache
}

Key flags: local scopes a variable to the function only, preventing it leaking into the rest of the script

Positional parameters in functions
Functions read their own arguments through $1, $@, and $#, separate from the script's own arguments.
Examples
backup() {
  local src="$1"
  local dest="$2"
  cp -r "$src" "$dest"
}
backup ~/docs /backup/docs
Shebang and execute permission
A script's first line tells the system which interpreter to use; it must be executable to run directly.
Examples
#!/bin/bash

chmod +x deploy.sh
./deploy.sh

Key flags: #!/usr/bin/env bash is more portable across systems where bash isn't always at /bin/bash

Sourcing a script
Runs a script's commands in the current shell rather than a subshell, so variables and functions persist afterwards.
Examples
source ./functions.sh
. ./functions.sh        # identical, the dot is shorthand
# vs. ./script.sh which runs in a separate subshell
getopts
Parses single-letter command-line flags inside a script.
Examples
while getopts "f:v" opt; do
  case $opt in
    f) file="$OPTARG" ;;
    v) verbose=true ;;
  esac
done
# usage: ./script.sh -f input.txt -v
$BASH_SOURCE / dirname
Finds a script's own location, useful for referencing files relative to the script rather than the caller's working directory.
Examples
script_dir="$(dirname "${BASH_SOURCE[0]}")"
config="$script_dir/config.json"

15. Error Handling

Detecting and responding to failure in scripts — exit codes, safety flags, and cleanup on exit.

Most commands signal failure through their exit code rather than an exception. 0 means success; any non-zero value means something went wrong, and the specific number is command-defined.
$? and exit codes
Checks the exit status of the most recently run command.
Examples
grep "error" app.log
echo $?              # 0 if found, 1 if not found, 2 on a real error

ping -c1 server01 &>/dev/null
if [[ $? -eq 0 ]]; then echo "reachable"; fi
&& and ||
Short-circuit chaining — run the next command only on success (&&) or only on failure (||).
Examples
mkdir -p build && cd build && make
ping -c1 server01 || echo "server01 is down"
set -e / -u / -o pipefail
Script-wide safety options that turn silent failures into immediate, loud ones — standard practice at the top of any serious script.
Examples
#!/bin/bash
set -euo pipefail
# -e: exit immediately if any command fails
# -u: error on use of an unset variable
# -o pipefail: a pipeline fails if any stage fails, not just the last one
trap
Runs a command when the script receives a signal or exits, commonly used for cleanup.
Examples
trap 'rm -f /tmp/lockfile' EXIT
trap 'echo "Interrupted"; exit 1' INT TERM
exit
Ends a script immediately with a specific exit code.
Examples
if [[ ! -f "$config" ]]; then
  echo "Config not found" >&2
  exit 1
fi
VOutput, Automation & Security

16. Output & Formatting

Controlling where output goes and how it's formatted — redirection, here-docs, and tidy column output.

echo / printf
Write text to standard output. printf gives precise control over formatting; echo is quicker for simple cases.
Examples
echo "Hello, World!"
echo -e "Line1\nLine2"        # -e enables backslash escapes
printf "%-10s %5d\n" "Total:" 42
RedirectionMeaning
> fileRedirect stdout to a file, overwriting it
>> fileRedirect stdout to a file, appending
< fileUse a file as stdin
2> fileRedirect stderr only
&> fileRedirect both stdout and stderr
2>&1Merge stderr into stdout's destination
command > /dev/null 2>&1Discard all output
Here-documents
Feeds a multi-line block of text to a command's standard input, often used for embedding config or SQL inline in a script.
Examples
cat <<EOF > config.txt
host=db01
port=5432
EOF

mysql -u root <<SQL
SHOW DATABASES;
SQL
column
Formats whitespace or delimiter-separated text into clean, aligned columns.
Examples
cat /etc/passwd | column -t -s ':'
ps aux | column -t

17. Scheduled Tasks

Running commands automatically on a schedule — cron, one-off jobs, and the modern systemd timer alternative.

FieldAllowed values
Minute0-59
Hour0-23
Day of month1-31
Month1-12
Day of week0-7 (0 and 7 are both Sunday)
crontab
Edits and lists the current user's scheduled cron jobs.
Examples
crontab -e                          # edit your crontab
crontab -l                          # list current entries
0 2 * * * /home/conor/scripts/backup.sh      # every day at 2am
*/15 * * * * /home/conor/scripts/healthcheck.sh   # every 15 minutes
0 9 * * 1 /home/conor/scripts/weekly-report.sh    # 9am every Monday
at
Schedules a one-off command to run once at a specific future time, rather than repeating like cron.
Examples
at 10pm
at> /home/conor/scripts/shutdown-check.sh
at> Ctrl+D
atq          # list pending at jobs
atrm 3       # cancel job 3
systemd timers
Modern alternative to cron, defined as .timer units paired with a .service unit, with the advantage of full systemd logging via journalctl.
Examples
systemctl list-timers
# /etc/systemd/system/backup.timer:
#   [Timer]
#   OnCalendar=daily
#   [Install]
#   WantedBy=timers.target
sudo systemctl enable --now backup.timer
System-wide cron jobs can also be dropped as individual files into /etc/cron.d/ rather than editing a user's crontab directly — useful for jobs installed by packages or configuration management.

18. Logging & Journald

Finding out what happened and when — the systemd journal, traditional log files, and writing your own log entries.

journalctl
Queries the systemd journal — the central log for the kernel, services, and boot messages on any modern Ubuntu system.
Examples
journalctl -u nginx                  # logs for one service
journalctl -u nginx -f               # follow live, like tail -f
journalctl -b                        # logs since the current boot
journalctl --since "1 hour ago"
journalctl -p err                    # priority: err and above only

Key flags: -u unit, -f follow, -b this boot, -p priority (emerg, alert, crit, err, warning, notice, info, debug)

/var/log
Traditional plain-text logs still used by many applications alongside the systemd journal.
Examples
less /var/log/syslog
tail -f /var/log/auth.log         # authentication and sudo attempts
zcat /var/log/syslog.1.gz | less  # rotated, compressed logs
logger
Sends a custom message into the system log from a script, useful for tracking your own automation alongside system events.
Examples
logger "Backup script completed successfully"
logger -t mybackup -p user.warning "Backup took longer than expected"
Log rotation (compressing and eventually deleting old logs) is handled automatically by logrotate, configured in /etc/logrotate.d/. You shouldn't normally need to touch it, but it's worth knowing it's there when disk space questions come up.

19. Security & Permissions

Locking things down — privilege escalation, the firewall, key-based authentication, and encryption.

sudo
Runs a single command with root privileges, with every use logged to /var/log/auth.log.
Examples
sudo apt update
sudo -l                  # list what you're allowed to run
sudo -v                  # refresh your sudo timestamp without running a command
visudo
Safely edits /etc/sudoers with syntax checking, preventing a typo from locking everyone out of sudo.
Examples
sudo visudo
sudo visudo -f /etc/sudoers.d/jdoe     # edit a drop-in file instead (preferred)
ufw
Ubuntu's friendly front-end for the kernel firewall (iptables/nftables underneath).
Examples
sudo ufw status verbose
sudo ufw allow 22/tcp           # allow SSH
sudo ufw allow from 192.168.1.0/24 to any port 5432
sudo ufw deny 23
sudo ufw enable
ssh-keygen
Generates an SSH key pair for passwordless, key-based authentication.
Examples
ssh-keygen -t ed25519 -C "conor@cmr-rig"
cat ~/.ssh/id_ed25519.pub      # the public key to share/install
gpg
Encrypts, decrypts, and signs files and messages.
Examples
gpg --gen-key
gpg -e -r recipient@example.com secret.txt    # encrypt for a recipient
gpg -d secret.txt.gpg                          # decrypt
fail2ban
Monitors logs for repeated failed login attempts and temporarily bans the offending IP at the firewall level. Install with apt; not present by default.
Examples
sudo apt install fail2ban
sudo fail2ban-client status sshd
VIAdvanced & Reference

20. Remote Access & SSH

Connecting to, copying files to, and working persistently on remote machines over SSH.

ssh
Opens a secure remote shell session on another machine.
Examples
ssh jdoe@server01
ssh -p 2222 jdoe@server01           # non-default port
ssh -i ~/.ssh/custom_key jdoe@server01
ssh jdoe@server01 "df -h"           # run one command remotely, no interactive session
ssh-copy-id
Installs your public key on a remote server's authorized_keys, enabling passwordless login afterwards.
Examples
ssh-copy-id jdoe@server01
~/.ssh/config
Saves connection shortcuts so you don't have to remember hostnames, ports, and key paths.
Examples
# ~/.ssh/config
Host rig
  HostName 192.168.1.50
  User conor
  Port 2222
  IdentityFile ~/.ssh/rig_key

ssh rig          # now just this
scp
Copies files to or from a remote machine over SSH.
Examples
scp report.pdf jdoe@server01:/home/jdoe/
scp jdoe@server01:/var/log/app.log ./
scp -r ./website/ jdoe@server01:/var/www/
rsync
Synchronises files and directories, only transferring the differences — faster and safer than scp for large or repeated transfers.
Examples
rsync -avz ./project/ jdoe@server01:/backup/project/
rsync -avz --delete ./local/ remote:/dest/    # mirror exactly, removing extras on the destination
rsync --dry-run -avz ./local/ remote:/dest/   # preview without actually copying

Key flags: -a archive mode, -v verbose, -z compress in transit, --delete mirror deletions

sftp
Interactive file transfer session over SSH, similar to old-school FTP but secure.
Examples
sftp jdoe@server01
sftp> get remote-file.txt
sftp> put local-file.txt
tmux / screen
Terminal multiplexers — keep a session running on a remote server even after you disconnect, and split it into multiple panes.
Examples
tmux new -s mysession
# detach: Ctrl+B then D
tmux attach -t mysession      # reconnect later
tmux ls                       # list sessions
SSH port forwarding
Tunnels a local or remote port through an SSH connection, useful for reaching a service that's only bound to localhost on a remote machine.
Examples
ssh -L 8080:localhost:80 jdoe@server01    # local port 8080 -> remote port 80

21. Package Management

Installing, updating, and removing software — apt and dpkg for .deb packages, plus snap.

ActionCommand
Update package indexsudo apt update
Upgrade installed packagessudo apt upgrade
Install a packagesudo apt install nginx
Remove a packagesudo apt remove nginx
Remove package + configsudo apt purge nginx
Remove unused dependenciessudo apt autoremove
Search for a packageapt search nginx
Show package detailsapt show nginx
List installed packagesapt list --installed
dpkg
Lower-level tool that apt sits on top of — works directly with .deb package files.
Examples
sudo dpkg -i package.deb            # install a local .deb file
dpkg -l | grep nginx                # is it installed?
dpkg -L nginx                       # list files a package installed
sudo dpkg --configure -a            # fix a half-configured install
apt-cache policy
Shows available versions of a package and which repository they come from, useful for diagnosing version pinning issues.
Examples
apt-cache policy nginx
add-apt-repository
Adds a third-party PPA (Personal Package Archive) as a software source.
Examples
sudo add-apt-repository ppa:some/ppa
sudo apt update
apt-mark hold
Pins a package at its current version, preventing it from being upgraded by future apt upgrade runs.
Examples
sudo apt-mark hold linux-image-generic
sudo apt-mark unhold linux-image-generic
snap
Ubuntu's sandboxed, auto-updating package format, used alongside apt for some applications.
Examples
snap list
sudo snap install code --classic
sudo snap refresh
sudo snap remove code

22. Environment Variables

Where environment variables come from, how to read and set them, and which startup files control them.

$PATH
The list of directories the shell searches for executables, in order.
Examples
echo $PATH
export PATH="$PATH:/opt/mytool/bin"     # add a directory for this session
env / printenv
Lists all environment variables, or runs a command with a modified environment.
Examples
printenv
printenv HOME
env VAR=value ./script.sh        # set a variable for one command only
FileLoaded whenTypical use
~/.bashrcEvery new interactive non-login shellAliases, prompt, shell options
~/.bash_profile / ~/.profileLogin shellsEnvironment variables, PATH
/etc/environmentSystem-wide, all users, all shell typesSystem-wide PATH and locale defaults
/etc/profile.d/*.shSystem-wide login shellsVendor or package-installed environment setup
Reloading config after edits
Changes to ~/.bashrc only take effect in new shells unless re-sourced.
Examples
source ~/.bashrc
# or simply open a new terminal tab
Persisting a variable permanently
Session-only export is lost when the terminal closes; add it to a startup file to make it permanent.
Examples
echo 'export EDITOR=vim' >> ~/.bashrc
source ~/.bashrc

23. Date & Time

Reading, formatting, and calculating with dates and times, plus controlling the system clock and timezone.

date
Shows or formats the current date and time.
Syntax
date [+FORMAT]
Examples
date
date +"%Y-%m-%d"               # 2026-06-16
date +"%Y-%m-%d %H:%M:%S"
date +"%A, %d %B %Y"            # Tuesday, 16 June 2026

Key flags: Common tokens: %Y year, %m month, %d day, %H hour (24h), %M minute, %S second, %A weekday name

date arithmetic
GNU date can calculate relative dates with -d, without needing a separate library.
Examples
date -d "yesterday"
date -d "3 days ago"
date -d "next monday"
date -d "2026-01-01 +6 months"
timedatectl
Views and sets the system clock, timezone, and NTP synchronisation status.
Examples
timedatectl
sudo timedatectl set-timezone Europe/London
timedatectl list-timezones | grep London
cal
Displays a simple calendar.
Examples
cal
cal 2026
cal 6 2026
sleep
Pauses execution for a given duration, commonly used in polling loops or to throttle scripts.
Examples
sleep 5             # 5 seconds
sleep 2m             # 2 minutes
sleep 1h             # 1 hour
time
Measures how long a command takes to run, including CPU vs. wall-clock time.
Examples
time ./build.sh

24. Math & Numbers

Doing arithmetic in the shell — bash's built-in integer math, bc for decimals, and number formatting.

Arithmetic expansion
Bash evaluates integer arithmetic directly with $(( )), no external command required.
Examples
echo $((5 + 3))          # 8
echo $((10 / 3))         # 3, integer division &mdash; bash has no native floats
echo $((10 % 3))         # 1, remainder
result=$((count * 2))
let / expr
Older ways to perform arithmetic, largely superseded by $(( )) but still seen in scripts.
Examples
let count=count+1
result=$(expr 5 + 3)
bc
A full arbitrary-precision calculator for anything bash's integer-only arithmetic can't handle, such as decimals.
Examples
echo "10 / 3" | bc -l         # 3.33333333333333333333
echo "scale=2; 22/7" | bc -l  # 3.14
Number formatting with printf
Formats numbers as padded, rounded, or differently-based strings.
Examples
printf "%05d\n" 42           # 00042
printf "%.2f\n" 3.14159      # 3.14
printf "%x\n" 255            # ff, hexadecimal
printf "%o\n" 8              # 10, octal
$RANDOM / shuf
Generates random numbers or shuffles input lines.
Examples
echo $RANDOM                      # random integer 0-32767
echo $((RANDOM % 6 + 1))          # dice roll, 1-6
shuf -i 1-50 -n 5                 # 5 unique random numbers from 1-50
seq
Generates a sequence of numbers, often used to drive a loop or feed another command.
Examples
seq 1 10
seq 0 5 100         # 0, 5, 10... up to 100
for i in $(seq 1 3); do echo $i; done

25. Aliases & Shell Config

Personalising the shell — shortcuts, prompt customisation, and behaviour tweaks, usually set once in dotfiles and forgotten about.

alias / unalias
Creates a shorthand for a longer command.
Examples
alias ll='ls -la'
alias gs='git status'
unalias ll

Key flags: Aliases set on the command line only last for the current session — add them to ~/.bashrc or ~/.bash_aliases to persist

~/.bash_aliases
The conventional file for storing aliases, sourced automatically from ~/.bashrc on Ubuntu's default setup.
Examples
# ~/.bash_aliases
alias ll='ls -la'
alias update='sudo apt update && sudo apt upgrade -y'
alias ..='cd ..'
Customising the prompt (PS1)
Controls what your shell prompt looks like — current directory, git branch, colours, and so on.
Examples
PS1='\u@\h:\w\$ '          # user@host:path$
# add to ~/.bashrc to make permanent

Key flags: Common tokens: \u username, \h hostname, \w full path, \W just the current directory name, \$ # for root, $ otherwise

shopt
Views and sets bash shell behaviour options.
Examples
shopt -s autocd            # type a directory name alone to cd into it
shopt -s histappend        # append to history file instead of overwriting
shopt -s globstar          # enables ** for recursive globbing
History configuration
Controls how much command history bash remembers and how it's stored.
Examples
export HISTSIZE=10000          # commands kept in memory per session
export HISTFILESIZE=20000      # commands kept on disk in ~/.bash_history
export HISTCONTROL=ignoredups  # don't store immediate duplicate commands