Skip to content

Exercises

This chapter provides hands-on exercises to practice bash scripting skills for real-world DevOps, SRE, and SysAdmin scenarios.


Create a script that checks system health:

  • CPU usage
  • Memory usage
  • Disk usage
  • Top 5 processes by memory
#!/usr/bin/env bash
check_cpu() {
top -bn1 | grep "Cpu(s)" | awk '{print "CPU: " $2}'
}
check_memory() {
free -h | awk '/^Mem:/ {print "Memory: " $3 "/" $2}'
}
check_disk() {
df -h | awk '/\/$/ {print "Disk: " $3 " used of " $2}'
}
check_top_processes() {
echo "Top 5 processes:"
ps aux --sort=-%mem | awk 'NR<=6 {print $11, $6"MB"}'
}
echo "=== System Health Check ==="
check_cpu
check_memory
check_disk
check_top_processes

Create a script to analyze Apache/Nginx logs:

  • Count requests by IP
  • Find most visited pages
  • Show error count
#!/usr/bin/env bash
LOG_FILE="${1:-/var/log/nginx/access.log}"
echo "=== Log Analysis ==="
echo "Requests by IP:"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -5
echo -e "\nMost visited pages:"
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -5
echo -e "\nError count:"
grep -c " 5[0-9][0-9] " "$LOG_FILE"

Create a backup script that:

  • Backs up specified directories
  • Creates timestamped archives
  • Cleans up old backups
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/backup"
SOURCE_DIRS=("/home" "/etc" "/var/www")
DAYS_TO_KEEP=7
timestamp=$(date +%Y%m%d_%H%M%S)
backup_file="$BACKUP_DIR/backup_$timestamp.tar.gz"
mkdir -p "$BACKUP_DIR"
tar -czf "$backup_file" "${SOURCE_DIRS[@]}"
echo "Backup created: $backup_file"
# Cleanup old backups
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$DAYS_TO_KEEP -delete
echo "Old backups cleaned up"

Create a script for user management:

  • Add new users with home directory
  • List all users
  • Lock/unlock accounts
#!/usr/bin/env bash
add_user() {
local username="$1"
sudo useradd -m "$username"
echo "User $username created"
}
list_users() {
awk -F: '{print $1, $6}' /etc/passwd
}
lock_user() {
sudo usermod -L "$1"
echo "User $1 locked"
}
unlock_user() {
sudo usermod -U "$1"
echo "User $1 unlocked"
}
case "$1" in
add) add_user "$2" ;;
list) list_users ;;
lock) lock_user "$2" ;;
unlock) unlock_user "$2" ;;
esac

Create a network diagnostics script:

  • Check connectivity to hosts
  • Show listening ports
  • Display network interface info
#!/usr/bin/env bash
check_hosts() {
local hosts=("google.com" "8.8.8.8" "cloudflare.com")
for host in "${hosts[@]}"; do
if ping -c 1 "$host" &>/dev/null; then
echo "$host is reachable"
else
echo "$host is unreachable"
fi
done
}
list_ports() {
echo "Listening ports:"
ss -tuln | awk 'NR>1 {print $1, $5}' | column -t
}
network_info() {
ip addr show | awk '/inet / {print "IP:", $2}'
ip route | awk '/default / {print "Gateway:", $3}'
}
echo "=== Network Diagnostics ==="
check_hosts
echo
list_ports
echo
network_info

Create a script to manage Docker containers:

  • Start/Stop/Restart containers
  • Show container status
  • View logs
#!/usr/bin/env bash
container_status() {
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
}
start_container() {
docker start "$1" && echo "Started: $1"
}
stop_container() {
docker stop "$1" && echo "Stopped: $1"
}
restart_container() {
docker restart "$1" && echo "Restarted: $1"
}
view_logs() {
docker logs --tail 50 "$1"
}
case "$1" in
status) container_status ;;
start) start_container "$2" ;;
stop) stop_container "$2" ;;
restart) restart_container "$2" ;;
logs) view_logs "$2" ;;
esac

Create a script to check SSL certificates:

  • Check certificate expiry
  • Show days remaining
  • Alert if expiring soon

<function_code> #!/usr/bin/env bash

check_ssl() { local domain=“$1” local port=”${2:-443}”

local expiry=$(echo | openssl s_client -servername "$domain" -connect "$domain:$port" 2>/dev/null | openssl x509 -noout -enddate)
if [ -z "$expiry" ]; then
echo "Error: Could not get certificate for $domain"
return 1
fi
local expiry_date=$(echo "$expiry" | cut -d= -f2)
local expiry_epoch=$(date -d "$expiry_date" +%s)
local now_epoch=$(date +%s)
local days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
echo "Domain: $domain"
echo "Expires: $expiry_date"
echo "Days remaining: $days_left"
if [ "$days_left" -lt 30 ]; then
echo "⚠ WARNING: Certificate expires in less than 30 days!"
return 1
fi
echo "✓ Certificate is valid"

}

for domain in ”$@”; do check_ssl “$domain” echo ”---” done </function_code>


Create a script to backup databases:

  • Backup MySQL/PostgreSQL
  • Compress and encrypt
  • Upload to remote storage
#!/usr/bin/env bash
set -euo pipefail
DB_TYPE="${DB_TYPE:-mysql}"
DB_NAME="${DB_NAME:-mydb}"
DB_USER="${DB_USER:-root}"
BACKUP_DIR="/backup/db"
REMOTE_HOST="backup-server"
timestamp=$(date +%Y%m%d_%H%M%S)
backup_file="$BACKUP_DIR/${DB_NAME}_${timestamp}.sql.gz"
mkdir -p "$BACKUP_DIR"
backup_mysql() {
mysqldump -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" | gzip > "$backup_file"
}
backup_postgres() {
pg_dump -U "$DB_USER" "$DB_NAME" | gzip > "$backup_file"
}
if [ "$DB_TYPE" = "mysql" ]; then
backup_mysql
elif [ "$DB_TYPE" = "postgres" ]; then
backup_postgres
fi
echo "Database backup created: $backup_file"
# Upload to remote
scp "$backup_file" "$REMOTE_HOST:/backups/"
echo "Backup uploaded to remote"

In this chapter, you completed:

  • ✅ System health check script
  • ✅ Log file analyzer
  • ✅ Automated backup script
  • ✅ User management script
  • ✅ Network diagnostics
  • ✅ Docker container manager
  • ✅ SSL certificate checker
  • ✅ Database backup script

Practice these exercises and modify them for your specific use cases. Refer back to earlier chapters for detailed explanations of specific commands and techniques.


Previous Chapter: Interview Questions End of Guide