Three Lines of Bash Stand Between Your Cron Job and a Silent Outage
Level: Intermediate · Time: 6 min · Outcome: A hardened, ShellCheck-clean cron wrapper generated for you
Three separate incidents taught me the same lesson over about a year. A /1...
Level: Intermediate · Time: 6 min · Outcome: A deploy that waits for its dependencies instead of racing them
I once spent forty minutes at eleven at night debugging a deploy that wasn't broken. The release script ran the database migration, the migr...
My Backup Hadn't Run in 9 Days and Nothing Told Me
Level: Intermediate · Time: 5 min · Outcome: A cron command that can't hang forever
The backup ran fine every night for fourteen months, and then it didn't run for nine days, and nothing told me. ...
A /1 rsync took our staging box to a load average of 41 one afternoon, and it took me longer than I want to admit to work out why. The sync normally finished in about twenty seconds. That day the backup target's NFS mount went sluggish, the sync star...
> Bash variables are global by default, so a helper function clobbered the caller's path variable and rm -rf cleaned up the wrong directory. local, return-as-status, and getopts — all in one incident.
Tags: #bash #linux #scripting #devops
The ...
We kept a plaintext file of hostnames, one per line, and a monitoring script read the file and pinged each host every five minutes. When a host failed to respond, the script sent an email alert. The system had been running for months and it worked — ...
The nightly backup looped over for f in $ls /data/exports and copied each file to a backup volume. It exited clean every night. For three weeks, green exit codes, no errors, nothing in the logs to suggest anything was wrong. The backup script had bee...
I meant to delete the .cache files under a data directory. The server had been running for two months and the cache layer had grown to about 14GB. The application team told me it was safe to purge it — they'd rebuilt the cache logic and the old files...
The backup ran every night at 2am and emailed me a green "847 files archived" summary. I'd built it, tested it against my own home directory where every file was named like report2024.csv, watched it sail through, and shipped it. For weeks the summar...
For three weeks a deployment pipeline reported every step green and shipped a build that had failed to compile on every single run. The build step ended in npm run build | tee build.log so the output could be archived. That pipe is the whole story: b...
A backup script of mine created a lock file on startup so two copies couldn't run at once — sensible. Then one night it hit an error partway through, set -e killed it on the spot, and it died without ever reaching the line that removes the lock. The ...
Every time I provision a new server — whether it's a $5 DigitalOcean droplet for a side project or a client's production box — there's a set of scripts I copy to /opt/scripts before I do anything else.
Not after the app is deployed. Not after the fi...
Nobody announces small features. You ship them, they're in there, and the people who find them either notice or they don't. I want to start documenting these because some of them are the kind of thing that makes a tool actually worth using day-to-day...
A client handed me SSH access to a server they'd been running for two years.
No documentation. No handoff notes. No "here's what's running and why." Just a root password in a LastPass share and a Slack message that said "it hosts our web app, let us...
certbot had been running quietly on my server for almost two years without a single issue.
Automatic renewals. Silent cron job. I never thought about it. Set it up once, tested it once, and mentally moved it to the "solved" column of my infrastructu...
Here's a script that will ruin your day:
!/bin/bash
cd /nonexistent/folder
rm -rf
echo "Done"
The cd fails because the folder doesn't exist. Bash ignores the failure. rm -rf runs in whatever directory you were already in. The script prints "Done...
I used to open files to search for things.
A config had the wrong database host somewhere. I knew it was in one of the files in /etc/nginx/ but I didn't know which one. So I opened nginx.conf. Searched. Not there. Opened sites-available/default. Sea...
Every time I SSH into a server, the first thing I want to know is: how's it doing?
Not a deep dive. Not a monitoring dashboard. Just the basics: how long has it been running, how much RAM is left, is the disk getting full, what's the IP. Five things...
My project folder used to look like this:
new-site/
new-site-2/
new-site-final/
new-site-final-ACTUAL/
test-backup/
backup-old/
Yours probably looks similar. We've all been there. You start a project, name the folder something reasonable, and then...
ShellCheck Error Codes Explained: How to Decode, Fix, and Prevent the Most Common Bash Warnings
Level: Beginner to Intermediate
Time: ~10 minutes
What you'll leave with: A clear understanding of ShellCheck's error code system, how to fix the on...