Brskanje po nacionalni mreži sem naletel na zanimiv članek (ki ga sem besedilno prinesel sem, ker je mojstrsko razložen), kjer nam avtor pokaže, kako narediti naše Bash skripte bolj robustne z uporabo Pasti.
S pasti naredite svoje bash skripte robustnejše
Predstavljajte si, da imate bash skript, ki se izvaja vsak dan vsakih šest ur in da se v določenem trenutku zruši ali pa isti skript teče dvakrat hkrati. Ti dve situaciji sta precej neprijetni, saj zahtevata popravek človekovega posega ali pa ju v določenih trenutkih ni mogoče obravnavati, sistem pa ostane v neskladnem stanju. Rešitev za to je med drugim tudi uporaba pasti.
Pasti je preprost in učinkovit način za nadzor izpisa bash skriptov. Vrnimo se k isti začetni situaciji, če se skript ročno ustavi, na primer s ctrl-c, se prekine in vrne izhodni signal
INT
in če se konča z
kill
potem bi bil izhod
TERM
.
Vse možne izhodne kode si lahko ogledate s
kill -l
vendar so najbolj uporabljeni natančno
INT, TERM, IZHOD
Če je skript na primer sinhroniziran z datotekami
rsync
najbolj smiselno je, da se zanesete na zaklepno datoteko, ki ne omogoča, da se skript zažene hkrati:
LOCK = "/ var / run / rsync.lock" če [! -e $ LOCK]; nato se dotaknite $ LOCK rsync -avz foo bar rm $ LOCK else echo "rsync se že izvaja" fi
V preprosti španščini zgornji skript preveri, ali datoteka za zaklepanje obstaja in če ne obstaja, jo ustvari in nato izvrši ustrezen ukaz ter na koncu izbriše datoteko za zaklepanje. Če datoteka obstaja, skript uporabniku preprosto pošlje sporočilo, ki označuje, da se ukaz že izvaja.
Vendar se v težavnih okoliščinah lahko zgodi, da datoteka zaklepanja ne bo odstranjena in bo uničila neželene učinke. Rešitev je zelo preprosta:
LOCK = "/ var / run / rsync.lock" če [! -e $ LOCK]; nato ujame "rm -f $ LOCK; izhod" INT TERM EXIT dotakni se $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync se že izvaja" fi
Posebnost te rešitve je, da je ukaz zaprt v past, tako da ob prejemu signala
INT, TERM, IZHOD
skript se ustavi in izbriše datoteko za zaklepanje.
Treba je povedati, da bi lahko v zgornjem scenariju med preverjanjem datoteke za zaklepanje in njenim ustvarjanjem obstajala konkurenca. Ena od možnih rešitev bi bila uporaba preusmeritve in bashovega načina noclobber, ki ne preusmeri na obstoječo datoteko:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; nato ujame 'rm -f "$ LOCK"; zapustiti $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync se že izvaja: $ (cat $ LCK)" fi
Posebnost slednjega je, da se uporablja, kot sem že rekel, način noclobber in da datoteka zaklepanja vsebuje PID procesa, ki se izvaja.
Omeniti velja tudi, da obstajajo tudi druge rešitve, kot so
flock
o
solo
vendar sem v tej objavi želel deliti rešitve z lastnimi sredstvi basha. S tem lahko izveste nekaj več o pasti odličen vodnik.
Super! Hvala za deljenje.
Lep članek, samo spremenite 'echo "rsync se že izvaja: $ (cat $ LCK)"' v 'echo "rsync se že izvaja: $ (cat $ LOCK)"'
pozdrav
Zelo zanimiv članek, ja gospod! To obdržim.
To je zelo koristen ukaz, ki ga je treba upoštevati. Uporabil sem ga v skriptu, ki sem ga objavil v objavi, za brisanje nekaterih datotek, ki jih je skript ustvaril, ko je bil ustavljen.
Zelo zanimivo, ja, gospod.