Bash er ikke det mest elegante språket jeg bruker. Det har merkelig syntaks, feilhåndtering er opt-in, og debugging er smertefullt. Men det er installert overalt — på servere, i CI/CD-pipelines, i Docker-containere — og for raske automatiseringsoppgaver er det uslåelig.
Jeg bruker Bash daglig: git hooks, deployment-scripts, backup-rutiner, og små verktøy som limer sammen resten av verktøykjeden min.
Når Bash over Python
Tommelregelen min er enkel. Hvis scriptet er under 50 linjer og primært kaller andre kommandoer — Bash. Hvis det involverer kompleks logikk, datastrukturer, eller API-kall — Python. Bash er limet mellom verktøy, ikke verktøyet selv.
Git hooks er et godt eksempel. En pre-commit hook som kjører linting og typesjekkinger trenger ikke Python — det er bare noen kommandoer i sekvens. Deployment-scripts som bygger, tester og pusher en Docker-container er en annen klassiker. Bash er perfekt for å orkestrere prosesser.
Feilhåndtering: Det viktigste
Det største problemet med Bash-scripts er at de fortsetter å kjøre etter feil som standard. En mislykket docker build følges av en docker push av det gamle imaget, og plutselig er produksjonen ødelagt. Løsningen er alltid de tre første linjene i ethvert script:
set -euo pipefail-e avbryter scriptet ved feil. -u feiler på udefinerte variabler. -o pipefail sørger for at en feil i en pipe ikke blir skjult av en suksess etterpå.
Eksempel: Deploy-script med feilhåndtering og rollback
#!/usr/bin/env bash
set -euo pipefail
APP="tuli-api"
IMAGE="gcr.io/tuli/${APP}"
PREV_TAG=$(gcloud run services describe "$APP" --format='value(spec.template.spec.containers[0].image)' 2>/dev/null || echo "")
cleanup() {
if [[ $? -ne 0 && -n "$PREV_TAG" ]]; then
echo "Deploy feilet — ruller tilbake til $PREV_TAG"
gcloud run deploy "$APP" --image="$PREV_TAG" --quiet
fi
}
trap cleanup EXIT
echo "Bygger $IMAGE..."
docker build -t "${IMAGE}:latest" .
echo "Kjører tester..."
docker run --rm "${IMAGE}:latest" go test ./...
echo "Pusher image..."
docker push "${IMAGE}:latest"
echo "Deployer til Cloud Run..."
gcloud run deploy "$APP" --image="${IMAGE}:latest" --quiet
echo "Deploy fullført."trap cleanup EXIT er nøkkelen — uansett hvordan scriptet avsluttes, kjører cleanup-funksjonen. Hvis noe feiler etter at det forrige imaget ble registrert, ruller den tilbake automatisk. Ingen manuell intervensjon.
Oppsummering
Bash handler ikke om eleganse. Det handler om pålitelighet og portabilitet. Start med set -euo pipefail, bruk trap for opprydding, og hold scripts korte og fokuserte. For alt mer komplekst — bruk Python eller Go.
Del av en serie med tekniske guider der jeg går gjennom verktøyene og teknologiene jeg bruker i praksis.