Automation Scripts
Build practical automation scripts for backups, deployments, and system tasks.
Automation scripts are where shell skills turn into real value. The goal isnât âwrite code that works onceâ â itâs âwrite code that works repeatedly, safely, and is easy to operateâ.
Design Principles (productionâready)
- â˘Idempotent: running twice shouldnât break things
- â˘Observable: logs to stderr/syslog + clear exit codes
- â˘Safe defaults: fail fast (
set -euo pipefail), quote variables, validate inputs - â˘Configurable: flags/env vars instead of hardcoding paths
- â˘Locking: prevent overlapping runs (common with cron)
Backup Script Example
#!/bin/bash
set -e
BACKUP_DIR="/backup/$(date +%Y%m%d)"
SOURCE="/home/pranav"
mkdir -p "$BACKUP_DIR"
tar -czvf "$BACKUP_DIR/home.tar.gz" "$SOURCE"
echo "Backup completed: $BACKUP_DIR"
set -e
BACKUP_DIR="/backup/$(date +%Y%m%d)"
SOURCE="/home/pranav"
mkdir -p "$BACKUP_DIR"
tar -czvf "$BACKUP_DIR/home.tar.gz" "$SOURCE"
echo "Backup completed: $BACKUP_DIR"
Improved pattern: safer mode + logging + validation
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
log() { echo "[INFO] $*" >&2; }
die() { echo "[ERROR] $*" >&2; exit 1; }
SOURCE="${1:-}"
[ -n "$SOURCE" ] || die "Usage: $0 /path/to/source"
[ -d "$SOURCE" ] || die "Source not found: $SOURCE"
BACKUP_ROOT="/backup"
BACKUP_DIR="$BACKUP_ROOT/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
log "Backing up $SOURCE to $BACKUP_DIR"
tar -czf "$BACKUP_DIR/archive.tar.gz" -C "$SOURCE" .
log "Done"
set -euo pipefail
IFS=$'\n\t'
log() { echo "[INFO] $*" >&2; }
die() { echo "[ERROR] $*" >&2; exit 1; }
SOURCE="${1:-}"
[ -n "$SOURCE" ] || die "Usage: $0 /path/to/source"
[ -d "$SOURCE" ] || die "Source not found: $SOURCE"
BACKUP_ROOT="/backup"
BACKUP_DIR="$BACKUP_ROOT/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
log "Backing up $SOURCE to $BACKUP_DIR"
tar -czf "$BACKUP_DIR/archive.tar.gz" -C "$SOURCE" .
log "Done"
Log Rotation Script
#!/bin/bash
LOG_DIR="/var/log/myapp"
MAX_SIZE=10485760 # 10MB
for log in "$LOG_DIR"/*.log; do
size=$(stat -f%z "$log" 2>/dev/null || stat -c%s "$log")
if [ "$size" -gt "$MAX_SIZE" ]; then
mv "$log" "$log.$(date +%Y%m%d)"
gzip "$log.$(date +%Y%m%d)"
fi
done
LOG_DIR="/var/log/myapp"
MAX_SIZE=10485760 # 10MB
for log in "$LOG_DIR"/*.log; do
size=$(stat -f%z "$log" 2>/dev/null || stat -c%s "$log")
if [ "$size" -gt "$MAX_SIZE" ]; then
mv "$log" "$log.$(date +%Y%m%d)"
gzip "$log.$(date +%Y%m%d)"
fi
done
Locking: prevent overlapping runs
If cron runs your script every 5 minutes but one run takes 8 minutes, youâll get overlaps.
Use a lock file or flock.
# Example using flock (preferred when available)
flock -n /var/lock/myjob.lock -c "/usr/local/bin/myjob.sh"
flock -n /var/lock/myjob.lock -c "/usr/local/bin/myjob.sh"
Scheduling + Observability
Automation should be âboringâ: scheduled, logged, and alerting on failures.
- â˘cron: simplest scheduler; redirect logs to a file
- â˘systemd timers: better logs + dependencies + status
â Practice (30 minutes)
- Write a script that rotates logs and adds a timestamp suffix, then compresses older logs.
- Add argument validation and a
--dry-runmode (print actions instead of executing). - Wrap it with
flockso overlapping runs canât happen.