Every developer has tasks they repeat daily. Setting up a local environment, running test suites, deploying to staging, cleaning up old branches, generating boilerplate. These tasks eat up time not because they are hard, but because they are frequent. The fix is almost always a shell script.

I spent a week tracking every terminal command I ran more than twice a day. The results were embarrassing. I was typing the same sequences of 4-5 commands dozens of times per week. That is when I started building a personal automation toolkit.

The Three-Minute Rule

If a task takes less than three minutes to do manually, most developers never bother automating it. That is a mistake. Three minutes done ten times a week is 30 minutes. Over a year, that is 26 hours - more than three full working days spent on a single repetitive task.

The rule I follow now: if I do something more than three times, I write a script for it. The script does not need to be perfect. It just needs to work.

Start With a Project Setup Script

The most impactful script I wrote was a project bootstrapper. Every time I started a new microservice, I was manually creating directories, copying config files, initializing git, setting up a Makefile, and configuring the CI pipeline. This took about 15 minutes each time.

#!/bin/bash
# new-service.sh - Bootstrap a new microservice

SERVICE_NAME=$1
if [ -z "$SERVICE_NAME" ]; then
  echo "Usage: new-service.sh "
  exit 1
fi

mkdir -p "$SERVICE_NAME"/{cmd,internal,pkg,configs,scripts}
cd "$SERVICE_NAME"

git init
cp ~/.templates/Makefile .
cp ~/.templates/.gitignore .
cp ~/.templates/Dockerfile .
cp ~/.templates/.github/workflows/ci.yml .github/workflows/

sed -i "s/SERVICE_NAME/$SERVICE_NAME/g" Makefile
go mod init "github.com/myorg/$SERVICE_NAME"

echo "Service $SERVICE_NAME created."

Fifteen minutes became five seconds. More importantly, every service now has a consistent structure, which makes onboarding and debugging much easier.

Git Cleanup Scripts

Another high-value target: git branch cleanup. After a few months on an active project, you accumulate dozens of stale local branches that have already been merged. Cleaning them manually is tedious.

#!/bin/bash
# clean-branches.sh - Remove merged local branches

git fetch --prune
BRANCHES=$(git branch --merged main | grep -v "main" | grep -v "\*")

if [ -z "$BRANCHES" ]; then
  echo "No merged branches to clean."
  exit 0
fi

echo "Removing merged branches:"
echo "$BRANCHES"
echo "$BRANCHES" | xargs git branch -d

I run this weekly. It keeps my local repo clean without any thought.

Log Watching and Alerts

When debugging services locally, I used to manually tail logs and scan for errors with my eyes. A simple wrapper script changed that completely.

#!/bin/bash
# watch-errors.sh - Tail logs and highlight errors

LOG_FILE=${1:-/var/log/app.log}
tail -f "$LOG_FILE" | while read LINE; do
  if echo "$LINE" | grep -qi "error\|panic\|fatal"; then
    echo -e "\033[31m$LINE\033[0m"
  else
    echo "$LINE"
  fi
done

Errors show up in red. No more scanning through walls of text. It is a tiny quality-of-life improvement, but it adds up over long debugging sessions.

Database Seeding

Setting up a local development database with test data was another recurring task. Instead of running SQL commands manually or clicking through a UI, I wrote a single script that drops the database, recreates it, runs migrations, and seeds test data. One command, and I have a clean development environment.

Making Scripts Discoverable

The biggest lesson I learned is that scripts you forget about are scripts you do not use. I keep all my personal automation in a single directory (~/scripts) which is added to my PATH. Each script has a consistent naming pattern and a help flag. I also keep a simple text file listing what each script does.

For project-specific scripts, I use a scripts/ directory at the root of the repo. This way, every team member benefits from the automation, and the scripts are version-controlled alongside the code they support.

The Compound Effect

None of these scripts are impressive on their own. Each one saves a few minutes. But collectively, they save hours per week and - more importantly - they reduce context switching. When a task is automated, you do not have to remember the exact sequence of steps. You do not have to worry about missing a step. You just run the script and move on to the actual problem you are trying to solve.

Start small. Pick the one task you did three times today and write a script for it tonight. You will thank yourself by Friday.