Surfując po krajowej sieci natknąłem się na interesujący artykuł (które przywołuję tutaj tekstowo, ponieważ jest mistrzowsko wyjaśnione), gdzie jego autor pokazuje nam, jak ulepszyć nasze skrypty Bash za pomocą Pułapki.
Ulepsz swoje skrypty bash za pomocą pułapek
Wyobraź sobie, że masz skrypt bash, który jest uruchamiany codziennie co sześć godzin i w którymś momencie ulega awarii lub ten sam skrypt uruchamia się dwukrotnie jednocześnie. Te dwie sytuacje są dość niewygodne, ponieważ wymagają skorygowania interwencji człowieka lub czasami nie można się nimi zająć, pozostawiając system w niespójnym stanie. Rozwiązaniem jest między innymi stosowanie pułapek.
Pułapki to prosty i skuteczny sposób kontrolowania wyników skryptów bash. Wróćmy do tej samej sytuacji wyjściowej, jeśli skrypt zostanie zatrzymany ręcznie np. Ctrl-c, to jest przerywany zwracając sygnał wyjściowy
INT
a jeśli to się kończy
kill
wtedy wynik byłby
TERM
.
Wszystkie możliwe kody wyjścia można wyświetlić za pomocą
kill -l
Jednak najczęściej używane są właśnie
WNĘTRZE, TERMIN, WYJŚCIE
Jeśli skrypt polega na przykład na synchronizacji plików z
rsync
najbardziej sensowną rzeczą jest poleganie na pliku blokującym, który nie pozwala na jednoczesne działanie skryptu:
LOCK = "/ var / run / rsync.lock" jeśli [! -e $ LOCK]; następnie dotknij $ LOCK rsync -avz foo bar rm $ LOCK else echo "rsync już działa" fi
W zwykłym hiszpańskim, poprzedni skrypt sprawdza, czy plik blokady istnieje, a jeśli nie istnieje, tworzy go, a następnie wykonuje odpowiednie polecenie, ostatecznie usuwając plik blokady. Jeśli plik istnieje, skrypt po prostu wysyła wiadomość do użytkownika wskazującą, że polecenie jest już uruchomione.
Jednak w przypadku problematycznej sytuacji może się zdarzyć, że plik blokady nie zostanie usunięty, niszcząc niepożądane efekty. Rozwiązanie jest bardzo proste:
LOCK = "/ var / run / rsync.lock" jeśli [! -e $ LOCK]; potem pułapka "rm -f $ LOCK; exit" INT TERM EXIT touch $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync już działa" fi
Specyfika tego rozwiązania polega na tym, że polecenie jest zamknięte w pułapce, tak że po odebraniu sygnału
WNĘTRZE, TERMIN, WYJŚCIE
skrypt zatrzymuje się i czyści plik blokady.
Warto powiedzieć, że w powyższym skrypcie może wystąpić sytuacja konkurencji między momentem weryfikacji pliku blokady a momentem jego utworzenia. Jednym z możliwych rozwiązań byłoby użycie przekierowania i trybu noclobber basha, który nie przekierowuje do istniejącego pliku:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; następnie trap 'rm -f "$ LOCK"; wyjść $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync już działa: $ (cat $ LCK)" fi
Osobliwością tego ostatniego jest to, że jest używany, jak już powiedziałem, w trybie noclobber i że plik blokady zawiera PID procesu, który jest wykonywany.
Warto też wspomnieć, że istnieją inne rozwiązania np
flock
o
solo
jednak w tym poście chciałem podzielić się rozwiązaniami z własnymi zasobami basha. Możesz dowiedzieć się trochę więcej o pułapkach dzięki temu doskonały przewodnik.
Świetny! Dzięki za udostępnienie.
Ładny artykuł, po prostu zmień 'echo' rsync już działa: $ (cat $ LCK) "'na' echo" rsync już działa: $ (cat $ LOCK) "'
pozdrowienia
Bardzo ciekawy artykuł, proszę pana! To trzymam.
Jest to bardzo przydatne polecenie, o którym należy pamiętać. Użyłem go w skrypcie, który opublikowałem w poście, aby usunąć niektóre pliki, które skrypt utworzył, gdy został zatrzymany.
Bardzo interesujące, proszę pana.