Strikte modus met set -euo pipefail
Schakel fail-fastgedrag in en begrijp precies welke fouten elke vlag van de strikte modus wel en niet opvangt.
Strikte modus met set -euo pipefail is een gratis DevOps-bootcamp-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject DevOps-bootcamp. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Waarom Bash standaard stilletjes faalt
Standaard blijft Bash doorgaan, zelfs wanneer opdrachten mislukken. Dat leidt in productiescripts tot subtiele rampen die moeilijk te debuggen zijn.
Neem dit script dat een back-up probeert te maken:
- Een typefout in een pad zorgt ervoor dat
cpmislukt - Bash negeert de fout en gaat door
- Het script meldt succes, hoewel er nooit een back-up van de gegevens is gemaakt
Dit is het probleem van stil falen. De strikte modus lost dit op door Bash zich als een gecompileerde taal te laten gedragen: stop onmiddellijk wanneer er iets misgaat.
#!/usr/bin/env bash
# Without strict mode — dangerous default behavior
cp /important/data /backups/data # fails (path doesn't exist)
echo "Backup complete" # still prints — false confidence!
rm -rf /tmp/staging # still runs — potentially destructiveDe drie belangrijkste vlaggen: set -euo pipefail
Je schakelt de strikte modus in door deze regel bovenaan elk script te plaatsen:
set -euo pipefail
Hiermee activeer je drie afzonderlijke beveiligingen:
-e— Sluit onmiddellijk af als een opdracht een status ongelijk aan nul retourneert-u— Behandel niet-ingestelde variabelen als een fout (in plaats van ze uit te breiden naar een lege tekenreeks)-o pipefail— Een pijplijn mislukt als een willekeurige opdracht erin mislukt, niet alleen de laatste
Samen vormen ze de standaard defensieve kop voor serieuze Bash-scripts. Elke vlag vangt een ander type bug op.
#!/usr/bin/env bash
set -euo pipefail
echo "Strict mode is now active"
echo "Every command failure will abort the script"set -e (errexit) begrijpen
set -e (ook geschreven als set -o errexit) zorgt ervoor dat het script onmiddellijk afsluit wanneer een opdracht eindigt met een status ongelijk aan nul.
Belangrijk gedrag:
- Eenvoudige opdrachten:
false,grep pattern file(geen overeenkomst) enls /nonexistentzorgen allemaal voor afsluiten - De afsluitcode van de laatste opdracht in het script wordt de afsluitcode van het script
- Opdrachten in
if-voorwaarden zijn uitgesloten —-ewordt niet geactiveerd voor de testexpressie - Opdrachten gevolgd door
|| truezijn eveneens uitgesloten (zie de volgende scènes)
Zie -e als je eerste verdedigingslinie tegen stil doorgaan na een fout.
#!/usr/bin/env bash
set -e
echo "Before failure"
ls /this/path/does/not/exist # exits here with code 2
echo "This line never runs"set -u (nounset) begrijpen
set -u (ook geschreven als set -o nounset) zorgt ervoor dat Bash elke verwijzing naar een niet-ingestelde variabele als een fatale fout behandelt.
Zonder -u wordt een typefout zoals $FLENAME in plaats van $FILENAME stilletjes uitgebreid naar een lege tekenreeks. Daardoor gedragen opdrachten zich onverwacht — of gevaarlijk (denk aan rm -rf "$TMPDIR/" wanneer $TMPDIR niet is ingesteld).
Belangrijke uitzonderingen:
${VAR:-default}— veilige vervanging door een standaardwaarde, activeert-uniet${VAR:+value}— voorwaardelijke uitbreiding, eveneens veilig"$@"en"$*"zijn vrijgesteld wanneer er geen positionele argumenten zijn doorgegeven
#!/usr/bin/env bash
set -euo pipefail
# Safe: provide a default for optional vars
OUTPUT_DIR="${1:-/tmp/output}"
LOG_LEVEL="${LOG_LEVEL:-info}"
echo "Writing to: $OUTPUT_DIR"
echo "Log level: $LOG_LEVEL"
# This would abort the script:
# echo "$UNDEFINED_VAR" # bash: UNDEFINED_VAR: unbound variable-o pipefail begrijpen
Zonder pipefail wordt de afsl status van een pijplijn uitsluitend bepaald door de laatste opdracht. Eerdere fouten worden stilletjes genegeerd.
Voorbeeld zonder pipefail:
cat /missing/file | wc -lcatmislukt met afsluitcode 1, maarwc -lslaagt met code 0- De pijplijn retourneert 0 — succes! Hoewel er gegevens verloren zijn gegaan.
Wanneer pipefail is ingeschakeld, retourneert Bash de afsluitcode van de meest rechtse opdracht die is mislukt. Daardoor worden fouten in pijplijnen zichtbaar en kunnen ze worden afgehandeld.
Let op: pipefail is geen lettervlag — deze moet worden ingesteld met -o pipefail.
#!/usr/bin/env bash
set -euo pipefail
# With pipefail: this aborts if grep finds nothing (exit 1)
# grep returns 1 when no match found
ps aux | grep "[n]ginx" | awk '{print $2}'
echo "If we reach here, nginx is running"Opzettelijk mislukte opdrachten — || true gebruiken
Soms mag een opdracht mislukken. Met set -e moet je expliciet aangeven welke fouten zijn toegestaan; anders wordt het script afgebroken.
De gebruikelijke oplossing is || true, waarmee je een terugval toevoegt die altijd slaagt:
command || true— de fout volledig negerencommand || echo "Warning: step failed, continuing"— de fout vastleggen en doorgaancommand || { echo "fatal"; exit 1; }— aangepaste foutafhandeling
Dit patroon maakt je bedoeling expliciet in de code: een gewone opdracht betekent "dit moet slagen"; || true betekent "dit mag mislukken en dat is geen probleem".
#!/usr/bin/env bash
set -euo pipefail
# Remove temp dir if it exists — OK if it doesn't
rm -rf /tmp/my_workspace || true
mkdir -p /tmp/my_workspace
# Check if a service is running — OK if not
if systemctl is-active --quiet nginx 2>/dev/null || true; then
echo "nginx is active"
fi
# Grep that may find nothing — OK
grep 'ERROR' /var/log/app.log || true
echo "Done"Wat set -e NIET opvangt
set -e heeft bekende uitzonderingen en valkuilen. Als je die begrijpt, voorkom je een vals gevoel van zekerheid:
- Opdrachten in voorwaarden van
if/while/until— de testexpressie is bewust vrijgesteld - Opdrachten die met
!worden ontkend —! falsezorgt niet voor afsluiten - De laatste opdracht vóór
||— bijvoorbeeldfalse || handle_error - De afsluitstatus van subshells in bepaalde contexten — bijvoorbeeld
VAR=$(failing_command)in sommige Bash-versies - Retourwaarden van functies — alleen de laatste opdracht in een functie telt
De strikte modus vervangt geen expliciete foutcontroles — het is een vangnet dat de meeste onbedoelde fouten opvangt.
#!/usr/bin/env bash
set -euo pipefail
# These do NOT trigger -e:
if false; then echo "never"; fi # -e exempt in conditions
! false # negation exempts
false || echo "handled" # || exempts the left side
# This DOES trigger -e (no condition, no ||):
# false
echo "Script continues after exempted failures"Subshells en functies met de strikte modus
Instellingen van de strikte modus worden overgenomen door subshells, maar gedragen zich subtiel in functies en opdrachtvervangingen.
Belangrijkste regels:
- Functies nemen
-e,-uenpipefailover van de aanroepende shell - Een retourwaarde ongelijk aan nul van een functie zorgt ervoor dat de aanroeper afsluit (wanneer
-eis ingesteld) — tenzij de aanroep in een voorwaarde staat of na||komt - Opdrachtvervanging
$(): in oudere Bash-versies activeert een mislukte opdracht binnen$()mogelijk niet-ein de bovenliggende shell; wijs de waarde toe en gebruik deze daarna afzonderlijk om veilig te zijn - Expliciete subshells
()nemen alle vlaggen over
#!/usr/bin/env bash
set -euo pipefail
setup_workspace() {
local dir="$1"
mkdir -p "$dir" # fails here if permissions denied
cd "$dir"
echo "Ready in $(pwd)"
}
# Safe pattern: assign result then use it
TODAY=$(date +%Y-%m-%d) # capture separately
WORKDIR="/tmp/run_${TODAY}"
setup_workspace "$WORKDIR"
echo "Workspace: $WORKDIR"De strikte modus combineren met fouttraps
De strikte modus vertelt Bash wanneer het moet stoppen. Met een trap op ERR kun je voordat het script afsluit opruimacties of diagnostiek uitvoeren.
Het gebruikelijke patroon is:
- Stel de strikte modus bovenaan in
- Definieer een functie
cleanupofon_error - Registreer deze met
trap 'on_error' ERR - Stel eventueel ook een trap in op
EXITvoor gegarandeerde opruimacties, ongeacht succes of mislukking
Belangrijk: gebruik set -E (hoofdletter E, ook errtrace genoemd) zodat de ERR-trap ook wordt overgenomen door functies en subshells — zonder deze instelling werken traps alleen in de hoofdtekst van de shell.
#!/usr/bin/env bash
set -Eeuo pipefail
on_error() {
local exit_code=$?
local line_number=${BASH_LINENO[0]}
echo "ERROR: command failed with code ${exit_code} at line ${line_number}" >&2
}
cleanup() {
echo "Cleaning up temporary files..." >&2
rm -rf /tmp/my_run_dir 2>/dev/null || true
}
trap on_error ERR
trap cleanup EXIT
mkdir -p /tmp/my_run_dir
echo "hello" > /tmp/my_run_dir/output.txt
cat /tmp/my_run_dir/output.txt
echo "Done"De strikte modus lokaal uitschakelen
Soms is een codeblok bewust "rommelig" — bijvoorbeeld wanneer je zoekt naar optionele hulpmiddelen of verouderde opdrachten uitvoert die om niet-foutredenen een waarde ongelijk aan nul retourneren. Je kunt de strikte modus tijdelijk uitschakelen en daarna herstellen.
Het veilige patroon:
- Sla de toestand op met
set +e(schakelt-euit), voer het blok uit en schakel de modus daarna opnieuw in metset -e - Of gebruik een subshell
( set +e; ... ), zodat de vlaggen van de bovenliggende shell nooit worden beïnvloed - Schakel de vlaggen altijd weer in zodra het risicovolle blok eindigt — het uitgeschakeld laten van vlaggen is een veelvoorkomende bron van bugs
Geef bij blokken met meerdere opdrachten de voorkeur aan de subshell-vorm, omdat deze de vlaggen bij het afsluiten automatisch herstelt.
#!/usr/bin/env bash
set -euo pipefail
# Probe for optional tools without aborting
HAS_JQ=false
(
set +e
command -v jq > /dev/null 2>&1
[[ $? -eq 0 ]] && echo "jq_found"
) && HAS_JQ=true || true
if [[ "$HAS_JQ" == "true" ]]; then
echo "jq is available — using JSON output"
else
echo "jq not found — using plain text"
fiEen compleet sjabloon voor een script met strikte modus
Hier is een productieklaar sjabloon waarin alle best practices voor de strikte modus uit deze les samenkomen:
set -Eeuo pipefail— alle vier de vlaggen, inclusieferrtraceIFS=$'\n\t'— veiliger splitsen van woorden (voorkomt splitsen op spaties)- ERR- en EXIT-traps voor diagnostiek en opruimacties
- Expliciete standaardwaarden voor optionele parameters
readonlyenlocalom het bereik van variabelen te beperken
Kopieer dit sjabloon aan het begin van elk niet-triviaal Bash-script om direct te profiteren van gedrag waarbij het script snel stopt en fouten traceerbaar zijn.
#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
# ── Constants ────────────────────────────────────────────
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "$0")"
# ── Trap handlers ────────────────────────────────────────
err_handler() {
echo "[${SCRIPT_NAME}] ERROR on line ${BASH_LINENO[0]}: exit ${?}" >&2
}
cleanup() {
echo "[${SCRIPT_NAME}] Exiting" >&2
}
trap err_handler ERR
trap cleanup EXIT
# ── Defaults ─────────────────────────────────────────────
ENV="${1:-production}"
MAX_RETRIES="${MAX_RETRIES:-3}"
# ── Main ─────────────────────────────────────────────────
main() {
echo "Running in env=${ENV}, max_retries=${MAX_RETRIES}"
echo "Script dir: ${SCRIPT_DIR}"
}
main "$@"Kennischeck: gedrag van pipefail
Test je begrip van de invloed van pipefail op de afsluitcodes van pipelines.
Samenvatting: strikte modus met set -euo pipefail
In deze les heb je geleerd hoe je Bash-scripts snel en duidelijk kunt laten falen met de strikte modus.
De drie vlaggen en waartegen ze beschermen:
-e(errexit) — stopt bij elke opdrachtstatus die niet nul is; wordt niet toegepast in voorwaarden en na||-u(nounset) — breekt af bij verwijzingen naar niet-ingestelde variabelen; gebruik${VAR:-default}voor optionele variabelen-o pipefail— laat een volledige pipeline falen als een willekeurige stap faalt, niet alleen de laatste
Aanvullende werkwijzen:
- Voeg
-E(errtrace) toe zodat ERR-traps worden doorgegeven aan functies - Gebruik
trapopERRenEXITvoor diagnostiek en opruimen - Gebruik
|| trueom fouten bewust toe te staan - Schakel de optie tijdelijk uit met
set +ein subshells voor verouderde code of code die iets controleert
De strikte modus is geen wondermiddel — ken de uitzonderingen — maar het is wel de effectiefste gewoonte voor het schrijven van betrouwbare, defensieve Bash-scripts.
Leer DevOps-bootcamp met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 142
- Lessen
- 568
Veelgestelde vragen
Is de les “Strikte modus met set -euo pipefail” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad DevOps-bootcamp, waaronder “Strikte modus met set -euo pipefail”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Wat leer ik in “Strikte modus met set -euo pipefail”?
Schakel fail-fastgedrag in en begrijp precies welke fouten elke vlag van de strikte modus wel en niet opvangt. Je oefent met DevOps-bootcamp door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met DevOps-bootcamp te beginnen?
Ervaring vooraf is niet nodig. DevOps-bootcamp op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Strikte modus met set -euo pipefail”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over DevOps-bootcamp?
Ja. Elke les over DevOps-bootcamp bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Strikte modus met set -euo pipefail
- Trap-handlers voor opruimen en signalen
- Veilige tijdelijke bestanden en vergrendelingsmappen
- Idempotente scripts en retrylogica met back-off