Navigând în rețeaua națională am dat peste un articol interesant (pe care îl aduc aici textual pentru că este explicat cu măiestrie) unde autorul său ne arată cum să ne facem scripturile bash mai robuste folosind Capcane.
Faceți scripturile bash mai robuste cu capcane
Imaginați-vă că aveți un script bash care rulează în fiecare zi la fiecare șase ore și că la un moment dat eșuează sau același script rulează de două ori simultan. Aceste două situații sunt destul de incomode, deoarece necesită corectarea intervenției umane sau, în anumite momente, nu pot fi abordate, lăsând sistemul într-o stare inconsistentă. Soluția la acest lucru, printre altele, este utilizarea capcanelor.
Traps este un mod simplu și eficient de a controla ieșirea scripturilor bash. Să revenim la aceeași situație inițială, dacă scriptul este oprit manual, de exemplu cu ctrl-c, este întrerupt returnând semnalul de ieșire
INT
iar dacă se termină cu
kill
atunci rezultatul ar fi
TERM
.
Toate codurile de ieșire posibile pot fi vizualizate cu
kill -l
cu toate acestea cele mai utilizate sunt cu precizie
INT, TERMEN, IEȘIRE
Dacă scriptul constă, de exemplu, în sincronizarea fișierelor cu
rsync
cel mai sensibil este să te bazezi pe un fișier de blocare care nu permite scriptului să ruleze simultan:
LOCK = "/ var / run / rsync.lock" dacă [! -e $ LOCK]; apoi atingeți $ LOCK rsync -avz foo bar rm $ LOCK altfel echo "rsync este deja în funcțiune" fi
În spaniolă simplă, scriptul de mai sus verifică dacă fișierul de blocare există și dacă nu există, îl creează și apoi execută comanda corespunzătoare, ștergând în cele din urmă fișierul de blocare. Dacă fișierul există, scriptul trimite pur și simplu un mesaj utilizatorului care indică faptul că comanda rulează deja.
Cu toate acestea, atunci când există o situație problematică, s-ar putea întâmpla ca fișierul de blocare să nu fie eliminat, distrugând efectele nedorite. Soluția este foarte simplă:
LOCK = "/ var / run / rsync.lock" dacă [! -e $ LOCK]; apoi trap "rm -f $ LOCK; exit" INT TERM EXIT atinge $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync deja rulează" fi
Particularitatea acestei soluții este că comanda este închisă într-o capcană, astfel încât atunci când este primit un semnal
INT, TERMEN, IEȘIRE
scriptul se oprește și șterge fișierul de blocare.
Merită să spunem că ar putea exista o situație de concurență în scriptul de mai sus între momentul verificării fișierului de blocare și momentul creării acestuia. O soluție posibilă ar fi utilizarea unei redirecționări și a unui mod noclobber bash care nu redirecționează către un fișier existent:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; apoi trap 'rm -f "$ LOCK"; ieșiți din $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync rulează deja: $ (cat $ LCK)" fi
Particularitatea acestuia din urmă este că este folosit așa cum am spus deja, modul noclobber și că fișierul de blocare conține PID-ul procesului care se execută.
De asemenea, merită menționat faptul că există și alte soluții precum
flock
o
solo
cu toate acestea, în această postare am vrut să împărtășesc soluțiile cu resursele proprii ale lui Bash. Puteți afla mai multe despre Capcane cu acest lucru ghid excelent.
Grozav! Vă mulțumim pentru distribuire.
Un articol frumos, doar schimbă 'echo "rsync rulează deja: $ (cat $ LCK)"' la 'echo "rsync rulează deja: $ (cat $ LOCK)"'
În ceea ce priveşte
Un articol foarte interesant, da domnule! Păstrez asta.
Este o comandă foarte utilă de reținut. L-am folosit într-un script pe care l-am publicat într-o postare, pentru a șterge câteva fișiere create de script atunci când a fost oprit.
Foarte interesant, da domnule.