Meena automates the morning checklist
Shell scripting, functions, loops — turn manual work into automation
Meena had been doing the same 15-minute manual health check every morning for 4 months. One Thursday she decided to automate it.
Any task you do more than twice should be a script.
Your first script:
#!/bin/bash
# The shebang line - always first. Tells Linux to use bash.echo "Hello from my first script"
echo "Running as: $(whoami) on $(hostname)"
echo "Time: $(date)"Save as hello.sh, then:
chmod +x hello.sh # make it executable
./hello.sh # run it
bash -x hello.sh # debug mode - prints every command as it runsVariables and if/else:
#!/bin/bash
set -euo pipefail # always add this - exits on any error safelyAPP="payment-service"
TODAY=$(date +%Y-%m-%d)
DISK=$(df / | awk 'NR==2{print $5}' | tr -d '%')if [ "$DISK" -gt 90 ]; then
echo "CRITICAL: Disk at ${DISK}%"
exit 1
elif [ "$DISK" -gt 80 ]; then
echo "WARNING: Disk at ${DISK}%"
else
echo "OK: Disk at ${DISK}%"
fiNumber comparisons: -gt (greater than), -lt (less than), -eq (equal), -ne (not equal).
File checks: -f (file exists), -d (directory exists), -z (string empty).
Loops:
# Check multiple servers:
for SERVER in web-01 web-02 web-03; do
ping -c 1 $SERVER > /dev/null 2>&1 && echo "$SERVER: UP" || echo "$SERVER: DOWN"
done# Wait for app after deployment (up to 3 minutes):
for i in {1..18}; do
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health)
[ "$HTTP" = "200" ] && echo "App is UP!" && exit 0
echo "Attempt $i/18 - waiting 10 seconds"
sleep 10
done
echo "App did not come up in 3 minutes"
exit 1Meena's morning health check script:
#!/bin/bash
set -euo pipefailSERVICES="payment-svc inventory-svc cart-svc"
LOG_DIR="/opt/app/logs"
STATUS="OK"log() { echo "[$(date '+%H:%M:%S')] $*"; }check_disk() {
local USAGE
USAGE=$(df / | awk 'NR==2{print $5}' | tr -d '%')
if [ "$USAGE" -gt 85 ]; then
STATUS="CRITICAL"
log "CRITICAL: Disk at ${USAGE}%"
else
log "OK: Disk at ${USAGE}%"
fi
}check_services() {
for SVC in $SERVICES; do
if systemctl is-active --quiet "$SVC"; then
log "OK: $SVC running"
else
STATUS="CRITICAL"
log "DOWN: $SVC is not running!"
fi
done
}log "=== Morning health check ==="
check_disk
check_services
log "Final status: $STATUS"
[ "$STATUS" = "OK" ] && exit 0 || exit 1Scheduled with cron at 7:30am. Four months of manual work, automated in 2 hours.
Golden rules for production scripts:
1. set -euo pipefail - fails safely on any error
2. cp file file.bak.$(date +%Y%m%d) - backup before every change
3. Log with timestamps
4. Always exit 1 on failure so callers know
5. bash -x script.sh for debugging
set -euo pipefail at the top of every production script — fail safely
$? is the exit code of the last command — 0 means success, non-zero means failure
Local variables inside functions avoid polluting global scope
bash -x script.sh prints every command as it runs — essential for debugging
chmod +x makes a script executable — required before running with ./