Сърфирайки в националната мрежа попаднах на интересна статия (което довеждам тук текстово, защото е майсторски обяснено), където авторът му ни показва как да направим нашите Bash скриптове по-здрави, използвайки Капани.
Направете вашите bash скриптове по-здрави с капани
Представете си, че имате bash скрипт, който се изпълнява всеки ден на всеки шест часа и че в един момент той се проваля или същият скрипт се изпълнява два пъти едновременно. Тези две ситуации са доста неудобни, тъй като изискват човешка намеса да бъде коригирана или в определени моменти не могат да бъдат адресирани, оставяйки системата в непоследователно състояние. Решението за това, наред с други, е използването на капани.
Traps е прост и ефективен начин за контрол на изхода на bash скриптове. Да се върнем към същата първоначална ситуация, ако скриптът бъде спрян ръчно, например с ctrl-c, той се прекъсва, връщайки изходния сигнал
INT
и ако завършва с
kill
тогава изходът ще бъде
TERM
.
Всички възможни кодове за изход могат да бъдат прегледани с
kill -l
Най-използваните обаче са точно
INT, СРОК, ИЗХОД
Ако скриптът се състои например от синхронизиране на файлове с
rsync
най-разумното е да разчитате на заключващ файл, който не позволява скрипта да се изпълнява едновременно:
LOCK = "/ var / run / rsync.lock" ако [! -e $ LOCK]; след това докоснете $ LOCK rsync -avz foo bar rm $ LOCK else echo "rsync вече работи" fi
На обикновен испански, горният скрипт проверява дали заключващият файл съществува и ако не съществува, той го създава и по-късно изпълнява съответната команда, като накрая изтрива заключващия файл. Ако файлът съществува, скриптът просто изпраща съобщение до потребителя, указващо, че командата вече се изпълнява.
Въпреки това, когато има проблемна ситуация, може да се случи, че файлът за заключване не е елиминиран, което разрушава нежеланите ефекти. Решението е много просто:
LOCK = "/ var / run / rsync.lock" ако [! -e $ LOCK]; след това прихванете "rm -f $ LOCK; излезте" INT TERM EXIT докоснете $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT друго ехо "rsync вече работи" fi
Особеността на това решение е, че командата е затворена в капана, така че при получаване на сигнал
INT, СРОК, ИЗХОД
скриптът спира и изчиства заключващия файл.
Струва си да се каже, че може да има ситуация на конкуренция в скрипта по-горе между времето на проверка на заключващия файл и времето, когато е създаден. Едно възможно решение би било да се използва пренасочване и режим noclobber на bash, който не пренасочва към съществуващ файл:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; след това хванете 'rm -f "$ LOCK"; изход $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync вече работи: $ (cat $ LCK)" fi
Особеността на последното е, че се използва, както вече казах, режим noclobber и че заключващият файл съдържа PID на процеса, който се изпълнява.
Също така си струва да се спомене, че има и други решения като
flock
o
solo
обаче в този пост исках да споделя решенията със собствените ресурси на bash. С това можете да научите малко повече за капаните отличен водач.
Страхотен! Благодаря за споделянето.
Хубава статия, просто променете 'echo "rsync вече работи: $ (cat $ LCK)"' на 'echo "rsync вече работи: $ (cat $ LOCK)"'
поздрави
Много интересна статия, да сър! Това го пазя.
Това е много полезна команда, която трябва да имате предвид. Използвах го в скрипт, който публикувах в публикация, за да изтрия някои файлове, които скриптът създаде, когато беше спрян.
Много интересно, да, сър.