Při procházení národní sítě jsem narazil na a zajímavý článek (který zde přináším textově, protože je mistrovsky vysvětlen), kde nám jeho autor ukazuje, jak udělat naše bash skripty robustnějšími pomocí Pasti.
Udělejte své bash skripty robustnějšími pomocí pastí
Představte si, že máte bash skript, který běží každý den každých šest hodin a že v určitém okamžiku selže nebo že stejný skript běží dvakrát současně. Tyto dvě situace jsou docela nepříjemné, protože vyžadují nápravu lidského zásahu nebo je někdy nelze řešit, což ponechává systém v nekonzistentním stavu. Řešením je mimo jiné použití pastí.
Traps je jednoduchý a efektivní způsob ovládání výstupu bash skriptů. Vraťme se ke stejné počáteční situaci, pokud je skript zastaven ručně, například pomocí ctrl-c, je přerušen a vrací výstupní signál
INT
a pokud to skončí
kill
pak by výstup byl
TERM
.
Všechny možné výstupní kódy lze zobrazit pomocí
kill -l
Nejpoužívanější jsou však přesně
INT, DOBA, KONEC
Pokud se skript skládá například ze synchronizace souborů s
rsync
nejrozumnější je spoléhat se na soubor zámku, který neumožňuje současné spuštění skriptu:
LOCK = "/ var / run / rsync.lock", pokud [! -e $ ZÁMEK]; potom klepněte na $ LOCK rsync -avz foo bar rm $ LOCK else echo "rsync již běží" fi
V obyčejné španělštině předchozí skript zkontroluje, zda soubor zámku existuje a pokud neexistuje, vytvoří jej a později provede příslušný příkaz a soubor zámku nakonec odstraní. Pokud soubor existuje, skript jednoduše odešle uživateli zprávu, že příkaz je již spuštěn.
Pokud však nastane problematická situace, může se stát, že soubor zámku nebude odstraněn, což zničí nežádoucí účinky. Řešení je velmi jednoduché:
LOCK = "/ var / run / rsync.lock", pokud [! -e $ ZÁMEK]; pak trap "rm -f $ LOCK; exit" INT TERM EXIT dotek $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync již běží" fi
Zvláštností tohoto řešení je, že příkaz je uzavřen v pasti, takže když je přijat signál
INT, DOBA, KONEC
skript se zastaví a vymaže soubor zámku.
Stojí za to říci, že ve výše uvedeném skriptu může existovat soutěžní situace mezi časem ověření souboru zámku a časem jeho vytvoření. Jedním z možných řešení by bylo použití přesměrování a režimu noclobber bash, který nepřesměruje na existující soubor:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; potom trap 'rm -f "$ LOCK"; ukončit $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync již běží: $ (cat $ LCK)" fi
Zvláštností druhé je, že se používá, jak jsem již řekl, režim noclobber a že soubor zámku obsahuje PID prováděného procesu.
Za zmínku také stojí, že existují i další řešení, jako např
flock
o
solo
nicméně v tomto příspěvku jsem chtěl sdílet řešení s vlastními zdroji bash. S tímto se můžete dozvědět něco více o trapech vynikající průvodce.
Brilantní! Děkuji za sdílení.
Pěkný článek, stačí změnit 'echo "rsync již běží: $ (cat $ LCK)"' na 'echo "rsync již běží: $ (cat $ LOCK)"'
pozdravy
Velmi zajímavý článek, ano, pane! To si nechávám.
Je to velmi užitečný příkaz, který je třeba mít na paměti. Použil jsem to ve skriptu, který jsem publikoval v příspěvku, k odstranění některých souborů, které skript vytvořil, když byl zastaven.
Velmi zajímavé, ano, pane.