Trap-käsittelijät siivousta ja signaaleja varten
Rekisteröi EXIT-, ERR- ja INT-trapit väliaikaistiedostojen poistamiseen ja keskeneräisten toimintojen luotettavaan peruuttamiseen.
Trap-käsittelijät siivousta ja signaaleja varten on ilmainen DevOps-bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu DevOps-bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Trap-käsittelijöiden merkitys
Kun Bash-komentosarja päättyy — normaalisti, virheen vuoksi tai käyttäjän painettua Ctrl+C — jäljelle voi jäädä väliaikaisia tiedostoja, keskeneräisiä tietoja tai rikkoutunut tila. Ilman siivousta nämä jäänteet kasaantuvat ja aiheuttavat vaikeasti jäljitettäviä ongelmia.
Trap-käsittelijät ratkaisevat tämän rekisteröimällä funktion tai komennon, jonka Bash suorittaa automaattisesti, kun tietty signaali tai pseudosignaali vastaanotetaan.
- EXIT — suoritetaan aina, kun komentosarja päättyy syystä riippumatta
- ERR — suoritetaan, kun jokin komento palauttaa nollasta poikkeavan poistumistilan
- INT — suoritetaan, kun käyttäjä lähettää SIGINT-signaalin (Ctrl+C)
- TERM — suoritetaan SIGTERM-signaalin yhteydessä (esimerkiksi komennosta
kill)
Hyvin kirjoitettu komentosarja rekisteröi nämä trap-käsittelijät heti alussa, ennen riskialttiiden toimintojen aloittamista.
trap-sisäänrakennetun komennon syntaksi
trap-sisäänrakennettu komento rekisteröi käsittelijän yhdelle tai useammalle signaalille tai pseudosignaalille. Yleinen syntaksi on:
trap 'command_or_function' SIGNAL [SIGNAL...]
Tärkeät säännöt:
- Ensimmäinen argumentti on lainausmerkeissä oleva shell-koodimerkkijono (tai funktion nimi), joka suoritetaan signaalin tapahtuessa.
- Käsittelijän jälkeen voi luetella useita signaaleja.
trap '' SIGNALohittaa kyseisen signaalin (tyhjä käsittelijä).trap - SIGNALpalauttaa signaalin oletustoiminnan.
Saman shellin kutsumat funktiot perivät trap-käsittelijät, mutta ( )- tai &-syntaksilla käynnistetyt alikomennot eivät peri niitä.
#!/usr/bin/env bash
# Syntax examples — not a full script
# Register a cleanup function on EXIT
trap cleanup EXIT
# Inline handler for INT and TERM
trap 'echo "Interrupted!"; exit 1' INT TERM
# Ignore SIGHUP
trap '' HUP
# Reset SIGPIPE to default
trap - PIPEEXIT-trap — turvaverkko
EXIT-pseudosignaali on tärkein rekisteröitävä trap-käsittelijä. Se suoritetaan, kun shell päättyy mistä tahansa syystä: normaalin suorituksen päättyessä, komennon exit N seurauksena, käsittelemättömän virheen vuoksi tai signaalin takia. Siksi se sopii erinomaisesti väliaikaisten tiedostojen poistamiseen.
Hyvä käytäntö:
- Luokaa väliaikaiset tiedostot komennolla
mktemp, jotta niiden nimet ovat yksilöllisiä ja ennalta arvaamattomia. - Tallentakaa polku heti muuttujaan.
- Rekisteröikää EXIT-trap heti luomisen jälkeen, jotta siivous suoritetaan aina.
Komentosarjan poistumiskoodi säilytetään — trap-käsittelijän poistumiskoodi ohitetaan, ellette kutsu sen sisällä nimenomaisesti komentoa exit.
#!/usr/bin/env bash
set -euo pipefail
TMPFILE=$(mktemp /tmp/myapp.XXXXXX)
cleanup() {
echo "Removing temp file: $TMPFILE" >&2
rm -f "$TMPFILE"
}
trap cleanup EXIT
# Do real work
echo "Processing..." > "$TMPFILE"
sort "$TMPFILE" -o "$TMPFILE"
cp "$TMPFILE" /tmp/myapp_result.txt
echo "Done. Result saved."Useiden väliaikaisten tiedostojen ja hakemistojen käsittely
Oikeat komentosarjat luovat usein useita väliaikaisia resursseja — tiedostoja, hakemistoja, FIFO-putkia ja lukitustiedostoja. Sen sijaan että seuraisitte jokaista erikseen, kerätkää ne taulukkoon ja poistakaa kaikki yhdellä siivousfunktiolla.
Tämä malli skaalautuu siististi: aina kun luotte uuden väliaikaisen resurssin, lisätkää se taulukkoon. EXIT-trap käsittelee aina koko luettelon riippumatta siitä, missä kohdassa komentosarja päättyy.
#!/usr/bin/env bash
set -euo pipefail
CLEANUP_TARGETS=()
add_cleanup() {
CLEANUP_TARGETS+=("$1")
}
cleanup() {
echo "Running cleanup..." >&2
for target in "${CLEANUP_TARGETS[@]:-}"; do
rm -rf "$target"
echo "Removed: $target" >&2
done
}
trap cleanup EXIT
# Create and track temp resources
TMPDIR_WORK=$(mktemp -d /tmp/work.XXXXXX)
add_cleanup "$TMPDIR_WORK"
TMPFILE_LOG=$(mktemp /tmp/run.XXXXXX.log)
add_cleanup "$TMPFILE_LOG"
echo "Working in $TMPDIR_WORK" | tee "$TMPFILE_LOG"
touch "$TMPDIR_WORK/output.txt"
echo "Step complete."ERR-trap — virheiden sieppaaminen
ERR-pseudosignaali suoritetaan, kun jokin yksinkertainen komento palauttaa nollasta poikkeavan poistumistilan, edellyttäen, että shell-asetus set -e (errexit) on käytössä tai komento ei ole if-, while- tai ||/&&-rakenteen sisällä.
Käyttäkää ERR-trapia seuraaviin tarkoituksiin:
- Kirjatkaa epäonnistunut rivi muuttujien
$LINENOja$BASH_COMMANDavulla. - Käynnistäkää palautuslogiikka ennen EXIT-trapin suorittamista.
- Tuottakaa jäsenneltyjä virheilmoituksia vakiovirtaan.
Tärkeää: ERR-trapeja ei suoriteta funktioiden sisällä, ellette suorita nimenomaisesti komentoa set -E (errtrace), jotta funktiot perivät ERR-trapin kutsuvalta shelliltä.
#!/usr/bin/env bash
set -eEuo pipefail
on_error() {
local exit_code=$?
local line=$1
echo "ERROR: command failed with exit code $exit_code at line $line" >&2
echo " Command: $BASH_COMMAND" >&2
}
trap 'on_error $LINENO' ERR
echo "Starting task..."
cp /nonexistent/file /tmp/ # This will fail
echo "This line is never reached."INT-trap — hallittu Ctrl+C-keskeytys
Ctrl+C-näppäinyhdistelmän painaminen lähettää SIGINT-signaalin edustalla olevalle prosessiryhmälle. Ilman trapiä Bash päättyy heti, jolloin keskeneräistä työtä voi jäädä jäljelle.
INT-trapin rekisteröiminen mahdollistaa seuraavat toimet:
- Tulostakaa käyttäjäystävällinen peruutusviesti.
- Tehkää tarvittava palautus ennen siirtymistä EXIT-trapille.
- Poistukaa merkityksellisellä tilakoodilla (
130on SIGINT-signaalin tavanomainen koodi:128 + 2).
Kun INT-käsittelijä on valmis, kutsukaa komentoa exit 130 oikean poistumiskoodin välittämiseksi. EXIT-trap suoritetaan tämän jälkeen automaattisesti.
#!/usr/bin/env bash
set -euo pipefail
TMPFILE=$(mktemp /tmp/demo.XXXXXX)
cleanup() {
rm -f "$TMPFILE"
echo "Temp file removed." >&2
}
on_interrupt() {
echo "" >&2
echo "Caught SIGINT — cancelling gracefully." >&2
exit 130 # EXIT trap (cleanup) runs automatically after this
}
trap cleanup EXIT
trap on_interrupt INT
echo "Running long task. Press Ctrl+C to cancel."
for i in $(seq 1 10); do
echo "Step $i/10..."
sleep 1
done
echo "All steps complete."EXIT-, ERR- ja INT-trapien yhdistäminen
Tuotantokäyttöön tarkoitetuissa komentosarjoissa rekisteröidään yleensä kaikki kolme trapiä yhdessä, jotta kaikki poistumisreitit katetaan:
- EXIT — suoritetaan aina ja huolehtii tiedostojen siivouksesta.
- ERR — kirjaa epäonnistuneen komennon ja rivinumeron.
- INT — tulostaa peruutusviestin ja poistuu koodilla 130.
Koska EXIT suoritetaan aina viimeisenä, siivouslogiikan tarvitsee olla vain yhdessä paikassa. ERR- ja INT-käsittelijät voivat keskittyä kirjaamiseen ja tilan asettamiseen ja jättää varsinaisen siivouksen EXIT-käsittelijälle kutsumalla komentoa exit.
Käyttäkää komennon set -eEuo pipefail yläosassa, jotta myös funktioiden virheet käynnistävät ERR-trapin ja pipefail havaitsee putkien sisäiset virheet.
#!/usr/bin/env bash
set -eEuo pipefail
TMPFILE=$(mktemp /tmp/combined.XXXXXX)
ROLLBACK_NEEDED=false
cleanup() {
if [[ "$ROLLBACK_NEEDED" == true ]]; then
echo "Rolling back partial changes..." >&2
fi
rm -f "$TMPFILE"
echo "Cleanup done." >&2
}
on_error() {
ROLLBACK_NEEDED=true
echo "ERR at line $1: $BASH_COMMAND" >&2
}
on_interrupt() {
echo "Interrupted by user." >&2
exit 130
}
trap cleanup EXIT
trap 'on_error $LINENO' ERR
trap on_interrupt INT
echo "hello" > "$TMPFILE"
echo "Script finished successfully."Trapien dynaaminen palauttaminen ja poistaminen käytöstä
Joskus trapia on muokattava kesken komentosarjan — esimerkiksi kertaluonteisen siivouksen jälkeen, kun kriittinen osuus on valmis, jotta myöhemmät normaalit toiminnot eivät käynnistä tarpeetonta palautusta.
trap - SIGNALpalauttaa signaalin sisäänrakennetun oletustoiminnan.trap '' SIGNALohittaa signaalin kokonaan (prosessi ei voi joutua sen lopettamaksi).- Uuden käsittelijän voi rekisteröidä milloin tahansa; viimeisin
trap-kutsu on voimassa.
Yleinen toimintamalli on päivittää EXIT-trap riskialttiin toiminnon onnistuttua ja vaihtaa palautuskäsittelijä yksinkertaiseen siivouskäsittelijään.
#!/usr/bin/env bash
set -euo pipefail
TMPFILE=$(mktemp /tmp/staged.XXXXXX)
rollback() {
echo "ROLLBACK: removing $TMPFILE" >&2
rm -f "$TMPFILE"
}
cleanup_only() {
echo "CLEANUP: removing $TMPFILE" >&2
rm -f "$TMPFILE"
}
# Start with rollback in case something fails during the risky phase
trap rollback EXIT
echo "Performing risky operation..."
echo "critical data" > "$TMPFILE"
# ... imagine more risky steps here ...
# Risky phase succeeded — switch to simple cleanup
trap cleanup_only EXIT
echo "Risky phase done. Now doing safe finalization."
cp "$TMPFILE" /tmp/staged_result.txt
echo "All done."Poistumiskoodien välittäminen trapien kautta
Hienovarainen ongelmakohta: jos siivousfunktio sisältää komentoja, jotka voivat epäonnistua, komentosarjan lopullinen poistumiskoodi saattaa muuttua. Säilyttäkää alkuperäinen poistumiskoodi nimenomaisesti.
Trap-käsittelijän sisällä $? sisältää trapin laukaisseen poistumiskoodin. Tallentakaa se käsittelijän ensimmäisellä rivillä ennen muita komentoja, jotka voisivat muuttaa sen.
#!/usr/bin/env bash
set -euo pipefail
TMPFILE=$(mktemp /tmp/exitcode.XXXXXX)
cleanup() {
local original_exit=$? # capture BEFORE any other command
echo "Cleaning up (original exit: $original_exit)" >&2
rm -f "$TMPFILE"
# Exit with the original code so callers see the real result
exit "$original_exit"
}
trap cleanup EXIT
echo "Doing work..."
echo "data" > "$TMPFILE"
# Simulate failure
if [[ ! -f /tmp/required_marker ]]; then
echo "Required marker missing!" >&2
exit 2
fi
echo "Done."Trapit funktioissa ja alikomennoissa
Trapien periytymisen ymmärtäminen on olennaista oikeiden komentosarjojen kirjoittamisessa:
- Funktiot suoritetaan samassa shellissä ja perivät trapit — mutta ERR välittyy funktioihin vain, kun
set -E(errtrace) on käytössä. - Alikomennot (
( ... )) aloittavat suorituksen vanhemman trapien kopiolla, mutta alikomennossa tehdyt muutokset eivät vaikuta vanhempaan. - Taustatyöt (
cmd &) ovat alikomentoja eivätkä peri vanhemman INT/TERM-trapeja (ne käyttävät signaalien oletuskäsittelyä).
Käytännön sääntö: pitäkää trapien rekisteröinti pääkomentosarjan rungossa, käyttäkää set -E-asetusta, kun ERR:n on välityttävä funktioihin, älkääkä koskaan luottako trapien periytymiseen &-rakenteen kautta.
#!/usr/bin/env bash
set -eEuo pipefail # -E = errtrace: ERR propagates into functions
on_error() {
echo "ERR in function or main at line $1" >&2
}
trap 'on_error $LINENO' ERR
risky_function() {
echo "Inside risky_function"
ls /nonexistent_path # triggers ERR — works because of set -E
}
# Subshell: has its own copy; changes don't affect parent
(
trap '' ERR # disable ERR only inside subshell
ls /nonexistent_path 2>/dev/null || true
echo "Subshell completed without triggering parent ERR"
)
risky_functionKäytännön malli: tiedoston atominen korvaaminen
Klassinen vikasietoinen Bash-malli on tiedoston atominen korvaaminen: kirjoittakaa väliaikaiseen tiedostoon ja nimetkää se sitten kohteensa paikalle. Jos jokin epäonnistuu ennen nimeämistä, alkuperäinen tiedosto säilyy muuttumattomana. Trapit tekevät tästä erittäin luotettavan.
Vaiheet:
- Luokaa väliaikainen tiedosto samassa tiedostojärjestelmässä kuin kohde, jotta
mvon atominen. - Rekisteröikää EXIT-trap poistamaan väliaikainen tiedosto, jos suoritus päättyy ennenaikaisesti.
- Kirjoittakaa uusi sisältö ja tarkistakaa se.
- Nimetkää tiedosto atomisesti uudelleen komennolla (
mv) — vasta nyt alkuperäinen korvataan. - EXIT-trap poistaa väliaikaisen tiedoston vain, jos se on edelleen olemassa (onnistuneen
mv-komennon jälkeen se on poistettu).
#!/usr/bin/env bash
set -euo pipefail
DEST="/tmp/important_config.conf"
TMPFILE=$(mktemp "$(dirname "$DEST")/.tmp.XXXXXX")
cleanup() {
rm -f "$TMPFILE" # no-op if mv already moved it
}
trap cleanup EXIT
# Write new content to temp file
cat > "$TMPFILE" <<'EOF'
[settings]
version=2
mode=production
EOF
# Validate before replacing
if ! grep -q 'version=' "$TMPFILE"; then
echo "Validation failed — aborting replacement" >&2
exit 1
fi
# Atomic rename — DEST is replaced only here
mv "$TMPFILE" "$DEST"
echo "Config updated atomically: $DEST"Tietotesti: ERR-trapin periytyminen
Testatkaa, miten ERR-trap toimii Bashin funktioiden kanssa.
Kertaus: trap-käsittelijät siivousta ja signaaleja varten
Tässä oppitunnissa opitte tekemään Bash-komentosarjoista vikasietoisia trap-käsittelijöiden avulla:
- EXIT on yleinen turvaverkko — rekisteröikää se heti minkä tahansa väliaikaisen resurssin luomisen jälkeen ja tallentakaa aina ensin
$?, jotta alkuperäinen poistumiskoodi säilyy. - ERR mahdollistaa virheiden kirjaamisen muuttujien
$LINENOja$BASH_COMMANDavulla; käyttäkääset -E-asetusta, jotta funktiot perivät sen. - INT käsittelee Ctrl+C:n hallitusti — tulostakaa viesti ja poistukaa koodilla 130, jolloin EXIT huolehtii siivouksesta.
- Kerätkää väliaikaiset resurssit taulukkoon ja poistakaa ne kaikki yhdellä siivousfunktiolla.
- Käyttäkää komentoa
trap - SIGNALsignaalin palauttamiseen ja komentoatrap '' SIGNALsignaalien dynaamiseen ohittamiseen. - Atominen uudelleennimeämismalli (
mktemp→ kirjoitus → tarkistus →mv) yhdistettynä EXIT-trapiin takaa, etteivät keskeneräiset kirjoitukset koskaan vioita kohdetiedostoa.
Komennon set -eEuo pipefail yhdistäminen oikein sijoitettuihin trapeihin tarjoaa vankan vikasietoisen perustan kaikille tuotantokäyttöön tarkoitetuille Bash-komentosarjoille.
Opi DevOps-bootcamp tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 142
- Oppitunnit
- 568
Usein kysytyt kysymykset
Onko oppitunti ”Trap-käsittelijät siivousta ja signaaleja varten” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa DevOps-bootcamp-oppimispolun 3 oppituntia, myös oppitunnin “Trap-käsittelijät siivousta ja signaaleja varten”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Trap-käsittelijät siivousta ja signaaleja varten”?
Rekisteröi EXIT-, ERR- ja INT-trapit väliaikaistiedostojen poistamiseen ja keskeneräisten toimintojen luotettavaan peruuttamiseen. Harjoittelet DevOps-bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni DevOps-bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin DevOps-bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Trap-käsittelijät siivousta ja signaaleja varten”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä DevOps-bootcamp-oppitunnilla?
Kyllä. Jokainen DevOps-bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Tiukka tila komennolla set -euo pipefail
- Trap-käsittelijät siivousta ja signaaleja varten
- Turvalliset väliaikaistiedostot ja lukitushakemistot
- Idempotentit skriptit ja uudelleenyritys viiveen kasvaessa