Przykład: użycie flocka do wymuszenia szeregowego działania skryptów z blokadami plików
Jednym z przykładów jest użycie blokady plików, aby zmusić skrypty do szeregowego uruchamiania w całym systemie. Jest to przydatne, jeśli nie chcesz, aby dwa skrypty tego samego rodzaju działały na tych samych plikach. W przeciwnym razie oba skrypty zakłócałyby się wzajemnie i powodowałyby uszkodzenie danych.
#exit if any command returns a non-zero exit code (like flock when it fails to lock)
set -e
#open file descriptor 3 for writing
exec 3> /tmp/file.lock
#create an exclusive lock on the file using file descriptor 3
#exit if lock could not be obtained
flock -n 3
#execute serial code
#remove the file while the lock is still obtained
rm -f /tmp/file.lock
#close the open file handle which releases the file lock and disk space
exec 3>&-
Użyj stada funkcjonalnie, definiując blokadę i odblokowanie
Możesz także zawinąć tę logikę blokowania / odblokowywania w funkcje wielokrotnego użytku. Następująca trap
wbudowana powłoka automatycznie zwolni blokadę pliku, gdy skrypt zakończy działanie (błąd lub sukces). trap
pomaga wyczyścić blokady plików. Ścieżka /tmp/file.lock
powinna być ścieżką zakodowaną na stałe, aby wiele skryptów mogło próbować się na niej zablokować.
# obtain a file lock and automatically unlock it when the script exits
function lock() {
exec 3> /tmp/file.lock
flock -n 3 && trap unlock EXIT
}
# release the file lock so another program can obtain the lock
function unlock() {
# only delete if the file descriptor 3 is open
if { >&3 ; } &> /dev/null; then
rm -f /tmp/file.lock
fi
#close the file handle which releases the file lock
exec 3>&-
}
Powyższa unlock
logika polega na usunięciu pliku przed zwolnieniem blokady. W ten sposób czyści plik blokady. Ponieważ plik został usunięty, inna instancja tego programu może uzyskać blokadę pliku.
Wykorzystanie funkcji blokowania i odblokowywania w skryptach
Możesz użyć go w swoich skryptach, jak w poniższym przykładzie.
#exit if any command returns a non-zero exit code (like flock when it fails to lock)
set -e
#try to lock (else exit because of non-zero exit code)
lock
#system-wide serial locked code
unlock
#non-serial code
Jeśli chcesz, aby Twój kod czekał, aż będzie mógł się zablokować, możesz dostosować skrypt w następujący sposób:
set -e
#wait for lock to be successfully obtained
while ! lock 2> /dev/null; do
sleep .1
done
#system-wide serial locked code
unlock
#non-serial code