Strikt läge med set -euo pipefail
Aktivera omedelbart avbrott vid fel och förstå exakt vilka fel varje flagga i strikt läge fångar och missar.
Strikt läge med set -euo pipefail är en gratis lektion i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Bemästra Linux-kommandoraden och Bash-skriptning, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Varför Bash som standard misslyckas tyst
Som standard fortsätter Bash att köra även när kommandon misslyckas. Det leder till subtila katastrofer i produktionsskript som är svåra att felsöka.
Föreställ dig följande skript som försöker skapa en säkerhetskopia:
- Ett stavfel i en sökväg gör att
cpmisslyckas - Bash ignorerar felet och fortsätter
- Skriptet rapporterar att allt lyckades, trots att data aldrig säkerhetskopierades
Detta är problemet med tysta fel. Strikt läge löser det genom att få Bash att bete sig som ett kompilerat språk: stoppa omedelbart när något går fel.
#!/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 tre centrala flaggorna: set -euo pipefail
Strikt läge aktiveras genom att placera följande rad nära början av varje skript:
set -euo pipefail
Detta aktiverar tre separata skydd:
-e— avsluta omedelbart om något kommando returnerar en status som inte är noll-u— behandla odefinierade variabler som ett fel (i stället för att expandera dem till en tom sträng)-o pipefail— en pipeline misslyckas om något kommando i den misslyckas, inte bara det sista
Tillsammans bildar de den vanliga defensiva inledningen för seriösa Bash-skript. Varje flagga fångar en egen typ av fel.
#!/usr/bin/env bash
set -euo pipefail
echo "Strict mode is now active"
echo "Every command failure will abort the script"Förstå set -e (errexit)
set -e (även skrivet som set -o errexit) gör att skriptet avslutas omedelbart när ett kommando avslutas med en status som inte är noll.
Viktiga beteenden att känna till:
- Enkla kommandon:
false,grep pattern file(ingen träff) ochls /nonexistentutlöser alla avslut - Det sista kommandots avslutskod i skriptet blir skriptets avslutskod
- Kommandon i
if-villkor är undantagna —-eaktiveras inte för testuttrycket - Kommandon som följs av
|| trueär också undantagna (se följande avsnitt)
Se -e som ditt första försvar mot att skriptet fortsätter tyst efter ett fel.
#!/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"Förstå set -u (nounset)
set -u (även skrivet som set -o nounset) gör att Bash behandlar alla referenser till odefinierade variabler som ett allvarligt fel.
Utan -u expanderas ett stavfel som $FLENAME i stället för $FILENAME tyst till en tom sträng, vilket får kommandon att bete sig oväntat — eller farligt (föreställ dig rm -rf "$TMPDIR/" när $TMPDIR inte är definierad).
Viktiga undantag:
${VAR:-default}— säker standardersättning som inte utlöser-u${VAR:+value}— villkorlig expansion, också säker"$@"och"$*"är undantagna när inga positionsargument har skickats
#!/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 variableFörstå -o pipefail
Utan pipefail avgörs en pipelines avslutningsstatus enbart av det sista kommandot. Tidigare fel slukas tyst.
Exempel utan pipefail:
cat /missing/file | wc -lcatmisslyckas med avslutskod 1, menwc -llyckas med kod 0- Pipelinen returnerar 0 — lyckat! Trots att data gick förlorade.
När pipefail är aktiverat returnerar Bash avslutskoden från det längst åt höger placerade kommandot som misslyckades. Då blir pipelinefel synliga och möjliga att fånga.
Obs! pipefail är inte en bokstavsflagga — den måste anges med -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"Avsiktliga kommando fel — använda || true
Ibland är det tillåtet att ett kommando misslyckas. Med set -e måste du uttryckligen ange vilka fel som tolereras; annars avbryts skriptet.
Den idiomatiska lösningen är || true, som lägger till en reservåtgärd som alltid lyckas:
command || true— ignorera felet heltcommand || echo "Warning: step failed, continuing"— logga och fortsättcommand || { echo "fatal"; exit 1; }— anpassad felhantering
Detta mönster gör din avsikt tydlig i koden: ett vanligt kommando betyder ”detta måste lyckas”; || true betyder ”detta får misslyckas, och det är okej”.
#!/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"Vad set -e INTE fångar
set -e har välkända undantag och fallgropar. Om du förstår dem undviker du falsk trygghet:
- Kommandon i villkor för
if/while/until— testuttrycket är avsiktligt undantaget - Kommandon som negeras med
!—! falseutlöser inte avslut - Det sista kommandot före
||— till exempelfalse || handle_error - Underprocessens avslutningsstatus i vissa sammanhang — till exempel
VAR=$(failing_command)i vissa Bash-versioner - Funktioners returvärden — endast det sista kommandot i en funktion räknas
Strikt läge ersätter inte uttrycklig felkontroll — det är ett skyddsnät som fångar de flesta oavsiktliga fel.
#!/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"Underprocesser och funktioner med strikt läge
Inställningar för strikt läge ärvs av underprocesser, men beter sig subtilt i funktioner och kommandosubstitutioner.
Viktiga regler:
- Funktioner ärver
-e,-uochpipefailfrån det anropande skalet - Ett icke-noll-returvärde från en funktion gör att det anropande skalet avslutas (när
-eär aktiverat) — såvida anropet inte finns i ett villkor eller följs av|| - Kommandosubstitution
$(): i äldre Bash kan ett misslyckat kommando inuti$()misslyckas med att utlösa-ei det överordnade skalet; tilldela värdet och använd det sedan separat för säkerhets skull - Explicita underprocesser
()ärver alla flaggor
#!/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"Kombinera strikt läge med felhantering
Strikt läge talar om för Bash när det ska stoppa. Med en trap på ERR kan du köra rensning eller diagnostik innan skriptet avslutas.
Det vanliga mönstret är:
- Aktivera strikt läge högst upp
- Definiera en funktion som heter
cleanupelleron_error - Registrera den med
trap 'on_error' ERR - Du kan även fånga
EXITför att garantera rensning oavsett om körningen lyckas eller misslyckas
Viktigt: använd set -E (stort E, även kallat errtrace) så att ERR-fällan också ärvs av funktioner och underprocesser — utan detta utlöses fällor endast i huvudskalets kod.
#!/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"Inaktivera strikt läge lokalt
Ibland är ett kodblock avsiktligt ”stökigt” — till exempel när du undersöker om valfria verktyg finns eller kör äldre kommandon som returnerar något annat än noll av skäl som inte beror på fel. Du kan tillfälligt inaktivera strikt läge och återställa det efteråt.
Det säkra mönstret:
- Spara tillståndet med
set +e(inaktiverar-e), kör blocket och aktivera sedan igen medset -e - Eller använd en underprocess
( set +e; ... )så att det överordnade skalets flaggor aldrig påverkas - Aktivera alltid flaggorna igen så snart riskblocket är klart — att lämna flaggorna avstängda är en vanlig felkälla
Föredra formen med underprocess när blocket innehåller flera kommandon, eftersom flaggorna då återställs automatiskt när underprocessen avslutas.
#!/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"
fiEn komplett mall för skript med strikt läge
Här är en produktionsklar mall som samlar alla bästa metoder för strikt läge som behandlas i den här lektionen:
set -Eeuo pipefail— alla fyra flaggor, inklusiveerrtraceIFS=$'\n\t'— säkrare orddelning (undviker delning vid blanksteg)- ERR- och EXIT-fällor för diagnostik och rensning
- Uttalade standardvärden för valfria parametrar
readonlyochlocalför att begränsa variabelomfattningen
Kopiera denna mall i början av varje Bash-skript som är mer än trivialt för att omedelbart dra nytta av att fel stoppar körningen snabbt och att fel kan spåras.
#!/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 "$@"Kunskapskontroll: pipefail-beteende
Testa era kunskaper om hur pipefail påverkar pipelines avslutskoder.
Repetition: strikt läge med set -euo pipefail
I den här lektionen lärde ni er hur ni kan få Bash-skript att avbryta tidigt och rapportera fel tydligt genom att använda strikt läge.
De tre flaggorna och vad de skyddar mot:
-e(errexit) — avslutar vid en status som inte är noll från ett kommando; undantas i villkor och efter||-u(nounset) — avbryter vid referenser till odefinierade variabler; använd${VAR:-default}för valfria variabler-o pipefail— gör att en hel pipeline misslyckas om något steg misslyckas, inte bara det sista
Kompletterande metoder:
- Lägg till
-E(errtrace) så att ERR-fällor ärvs av funktioner - Använd
trappåERRochEXITför diagnostik och städning - Använd
|| trueför att avsiktligt tolerera fel - Inaktivera tillfälligt med
set +ei subsheller för äldre kod eller undersökningskod
Strikt läge är ingen universallösning — lär er dess undantag — men det är den enskilt mest effektiva vanan för att skriva tillförlitliga och defensiva Bash-skript.
Lär dig Bash med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Strikt läge med set -euo pipefail” gratis?
Ja – hela texten till ”Strikt läge med set -euo pipefail” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Bemästra Linux-kommandoraden och Bash-skriptning, kan Ni uppgradera till CoddyKit PRO. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad lär jag mig i ”Strikt läge med set -euo pipefail”?
Aktivera omedelbart avbrott vid fel och förstå exakt vilka fel varje flagga i strikt läge fångar och missar. Ni övar på Bemästra Linux-kommandoraden och Bash-skriptning med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Bemästra Linux-kommandoraden och Bash-skriptning?
Du behöver inga förkunskaper. Utbildningen i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Strikt läge med set -euo pipefail”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Bemästra Linux-kommandoraden och Bash-skriptning-lektionen?
Ja. Varje Bemästra Linux-kommandoraden och Bash-skriptning-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Strikt läge med set -euo pipefail
- Trap-hanterare för städning och signaler
- Säkra temporära filer och låskataloger
- Idempotenta skript och logik för omförsök med backoff