Ce face trap
trap înregistrează o acțiune care se execută automat când shell-ul primește un semnal, de exemplu INT (Ctrl+C) sau TERM (cererea de oprire trimisă de kill). Pseudo-semnalul EXIT se declanșează la orice ieșire din script, normală sau cu eroare.
Cea mai frecventă utilizare este curățenia: ștergerea fișierelor temporare, eliberarea unui fișier de blocare (lock) sau oprirea proceselor pornite în fundal, indiferent cum se termină scriptul.
Bash mai are pseudo-semnalele ERR (după o comandă care eșuează), DEBUG (înaintea fiecărei comenzi) și RETURN. SIGKILL (9) și SIGSTOP nu pot fi interceptate.
Opțiuni și argumente
| Opțiune / Parametru | Descriere |
|---|---|
trap 'cmd' EXIT |
Rulează cmd când scriptul se termină, din orice motiv. |
trap 'cmd' INT TERM |
Rulează cmd la Ctrl+C sau la kill PID. |
trap '' INT |
Ignoră semnalul (șir gol): Ctrl+C nu mai oprește scriptul. |
trap - INT |
Revine la comportamentul implicit al semnalului. |
trap -p [SEMNAL] |
Afișează acțiunile înregistrate. |
trap -l |
Listează numele și numerele semnalelor. |
Exemple
Exemplul 1: Ștergerea fișierului temporar la ieșire
Funcția curata rulează la final, chiar dacă scriptul s-ar opri mai devreme din cauza unei erori.
curata() {
rm -f "$TMP"
echo "Fișierul temporar a fost șters"
}
TMP=$(mktemp ./lucru.XXXXXX)
trap curata EXIT
echo "Ana,9" > "$TMP"
echo "Lucrez cu un fișier temporar"
Rezultat
Lucrez cu un fișier temporar
Fișierul temporar a fost șters
Exemplul 2: Interceptarea semnalului TERM
Scriptul își trimite singur semnalul TERM. În loc să se oprească, rulează acțiunea din trap și continuă.
trap 'echo "Am primit SIGTERM, salvez starea"' TERM
trap -p TERM
kill -TERM $$
echo "Scriptul continuă"
trap - TERM
Rezultat
trap -- 'echo "Am primit SIGTERM, salvez starea"' SIGTERM
Am primit SIGTERM, salvez starea
Scriptul continuă
Exemplul 3: Oprire curată la Ctrl+C
Un script care rulează mult timp poate opri procesul din fundal și poate ieși cu codul 130 (convenția pentru Ctrl+C).
#!/usr/bin/env bash
opreste() {
echo "Opresc procesarea..."
kill "$PID_LUCRU" 2>/dev/null
exit 130
}
trap opreste INT TERM
sleep 600 &
PID_LUCRU=$!
echo "Procesez datele (Ctrl+C pentru oprire)"
wait "$PID_LUCRU"
Ieșire în terminal
Procesez datele (Ctrl+C pentru oprire)
^COpresc procesarea...
Greșeli frecvente
- Ghilimele duble în acțiune:
trap "rm $TMP" EXITînlocuiește$TMPîn momentul în care ruleazătrap, nu la ieșire. Folosește ghilimele simple sau o funcție. - Așteptarea ca
trap ... KILLsă funcționeze:SIGKILLnu poate fi interceptat, deci curățenia nu rulează dupăkill -9. - Un al doilea
trap ... EXITînlocuiește primul, nu se adaugă la el. Pune toate acțiunile într-o singură funcție de curățenie.
Comenzi înrudite
kill: Trimite un semnal de control sau oprire către un proces specificat prin ID (PID).exit: Încheie execuția shell-ului sau a scriptului curent și transmite un cod numeric de stare sistemului.set -euo pipefail: Face un script Bash să se oprească la prima eroare, la variabile nedefinite și la comenzi eșuate din pipeline.Funcții în Bash: Gruparea instrucțiunilor în blocuri reutilizabile de cod, cu variabile locale și parametri.