You repeat the same terminal commands daily. Copy files, process logs, deploy code - all manual, all error-prone. Shell scripting automates the tedious so you can focus on what matters. Here's the 20% of bash that handles 80% of real-world tasks.
Automate Everything
Write once, run forever. Shell scripts turn 10-step manual processes into a single command.
Core Concept
A shell script is just a text file with commands. Add a shebang, make it executable, and you have reusable automation:
Key Techniques
Variables & Args
Store values and accept command-line input
Conditionals
if/else, test operators, case statements
Loops
for, while, iterate over files and data
Functions
Reusable code blocks with parameters
Practical Examples
Variables and Arguments:
#!/bin/bash
# Variables
NAME="backup"
DATE=$(date +%Y-%m-%d)
DIR="/var/backups"
# Command-line arguments
# $0 = script name, $1 = first arg, $# = arg count
FILE=$1
DEST=${2:-$DIR} # Default value if not provided
echo "Backing up $FILE to $DEST/$NAME-$DATE"
Conditionals:
#!/bin/bash
# File tests
if [[ -f "$FILE" ]]; then
echo "File exists"
elif [[ -d "$FILE" ]]; then
echo "It's a directory"
else
echo "Not found"
fi
# String comparison
if [[ "$ENV" == "production" ]]; then
echo "Be careful!"
fi
# Numeric comparison
if [[ $COUNT -gt 10 ]]; then
echo "More than 10 items"
fi
# Multiple conditions
if [[ -f "$FILE" && -r "$FILE" ]]; then
echo "File exists and is readable"
fi
Loops:
#!/bin/bash
# Loop over files
for file in *.txt; do
echo "Processing $file"
wc -l "$file"
done
# Loop over arguments
for arg in "$@"; do
echo "Argument: $arg"
done
# Loop with sequence
for i in {1..5}; do
echo "Iteration $i"
done
# While loop
while read -r line; do
echo "Line: $line"
done < input.txt
Functions:
#!/bin/bash
# Define function
log() {
echo "[$(date '+%H:%M:%S')] $1"
}
# Function with return value
check_status() {
if curl -s "$1" > /dev/null; then
return 0 # Success
else
return 1 # Failure
fi
}
# Usage
log "Starting deployment"
if check_status "https://api.example.com"; then
log "API is healthy"
else
log "API is down!"
exit 1
fi
Why This Matters
- ✓ Eliminate Repetitive Tasks - Automate daily workflows that eat your time
- ✓ Reduce Human Error - Scripts don't forget steps or make typos
- ✓ Document Processes - Scripts serve as executable documentation
- ✓ Enable CI/CD - Build, test, and deploy pipelines are shell scripts
- ✓ Universal Skills - Works on Linux, macOS, WSL, containers, and servers
Cheatsheet
| Operator | Meaning | Example |
|---|---|---|
-f |
File exists | [[ -f file.txt ]] |
-d |
Directory exists | [[ -d /path ]] |
-z |
String is empty | [[ -z "$VAR" ]] |
-n |
String is not empty | [[ -n "$VAR" ]] |
-eq, -ne |
Equal, not equal (numbers) | [[ $X -eq 5 ]] |
-lt, -gt |
Less than, greater than | [[ $X -gt 10 ]] |
==, != |
String comparison | [[ "$A" == "$B" ]] |
&&, || |
AND, OR | [[ -f x && -r x ]] |
Special Variables:
| Variable | Meaning |
|---|---|
$0 |
Script name |
$1, $2... |
Positional arguments |
$# |
Number of arguments |
$@ |
All arguments (as separate words) |
$? |
Exit status of last command |
$$ |
Current process ID |
Pro Tips
Use Strict Mode
Start scripts with set -euo pipefail. This exits on errors (-e), undefined variables (-u), and pipe failures (-o pipefail).
Always Quote Variables
Use "$VAR" not $VAR. Unquoted variables break on spaces and can cause security issues with special characters.
Debug with -x
Run bash -x script.sh or add set -x to print each command before execution. Great for debugging.
Capture Command Output
Use result=$(command) to capture output into a variable. For both stdout and stderr: result=$(command 2>&1).
Clean Up with trap
Use trap cleanup EXIT to ensure cleanup functions run even if the script fails. Great for removing temp files.
Getting Started
-
1
Create Your Script
Create a file like
myscript.shand add#!/bin/bashat the top -
2
Add Strict Mode
Add
set -euo pipefailon line 2 to catch errors early -
3
Write Your Commands
Add the same commands you'd type in the terminal, one per line
-
4
Make It Executable
Run
chmod +x myscript.shto add execute permissions -
5
Run It
Execute with
./myscript.shorbash myscript.sh
Stop Repeating Yourself
Every command you type twice is a script waiting to be written. Start automating today.
Bash Reference Manual