Surfing det nationale netværk stødte jeg på en interessant artikel (som jeg bringer her tekstmæssigt, fordi det er mesterligt forklaret), hvor dens forfatter viser os, hvordan vi kan gøre vores Bash-scripts mere robuste ved hjælp af Fælder.
Gør dine bash-scripts mere robuste med fælder
Forestil dig, at du har et bash-script, der kører hver dag hver sjette time, og at det på et tidspunkt mislykkes, eller at det samme script kører to gange samtidigt. Disse to situationer er ganske ubehagelige, da de kræver, at menneskelig indgriben korrigeres, eller på bestemte tidspunkter ikke kan løses, hvilket efterlader systemet i en inkonsekvent tilstand. Løsningen på dette er blandt andet at bruge fælder.
Traps er en enkel og effektiv måde at kontrollere output fra bash-scripts. Lad os gå tilbage til den samme indledende situation, hvis scriptet stoppes manuelt, for eksempel med ctrl-c, afbrydes det, og returnerer udgangssignalet
INT
og hvis det ender med
kill
så ville output være
TERM
.
Alle mulige udgangskoder kan ses med
kill -l
dog de mest anvendte er præcist
INT, TERM, EXIT
Hvis scriptet f.eks. Består af filsynkronisering med
rsync
Den mest fornuftige ting er at stole på en låsefil, der ikke tillader scriptet at køre samtidigt:
LOCK = "/ var / run / rsync.lock" hvis [! -e $ LOCK]; tryk derefter på $ LOCK rsync -avz foo bar rm $ LOCK ellers ekko "rsync kører allerede" fi
På almindelig spansk kontrollerer det forrige script, om låsefilen findes, og hvis den ikke findes, opretter den den og udfører senere den tilsvarende kommando, hvorefter låsefilen slettes. Hvis filen findes, sender scriptet simpelthen en besked til brugeren om, at kommandoen allerede kører.
Men når der er en problematisk situation, kan det ske, at låsefilen ikke elimineres, hvilket ødelægger uønskede effekter. Løsningen er meget enkel:
LOCK = "/ var / run / rsync.lock" hvis [! -e $ LOCK]; fæld derefter "rm -f $ LOCK; afslut" INT TERM EXIT touch $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT ellers ekko "rsync kører allerede" fi
Særlige ved denne løsning er, at kommandoen er lukket i en fælde, så når et signal modtages
INT, TERM, EXIT
scriptet stopper og rydder låsefilen.
Det er værd at sige, at der kan være en konkurrencesituation i scriptet ovenfor mellem det tidspunkt, hvor låsefilen er verificeret, og den tid den oprettes. En mulig løsning ville være at bruge en omdirigering og bashs noclobber-tilstand, som ikke omdirigerer til en eksisterende fil:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; fæld derefter 'rm -f "$ LOCK"; afslutte $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT ellers ekko "rsync kører allerede: $ (cat $ LCK)" fi
Det særegne ved sidstnævnte er, at det bruges som jeg allerede havde sagt, noclobber-tilstanden, og at låsefilen indeholder PID for den proces, der udføres.
Det er også værd at nævne, at der er andre løsninger såsom
flock
o
solo
men i dette indlæg ville jeg dele løsningerne med bashs egne ressourcer. Du kan lære lidt mere om fælder med dette fremragende guide.
Store! Tak fordi du delte.
Dejlig artikel, bare skift 'echo "rsync kører allerede: $ (cat $ LCK)"' til 'echo "rsync kører allerede: $ (cat $ LOCK)"'
hilsen
En meget interessant artikel, ja sir! Dette holder jeg.
Det er en meget nyttig kommando at huske på. Jeg brugte det i et script, som jeg offentliggjorde i et indlæg, til at slette nogle filer, som scriptet oprettede, da det blev stoppet.
Meget interessant, ja sir.