Exemplo: usando flock para forçar scripts a serem executados em série com bloqueios de arquivo
Um exemplo é usar o bloqueio de arquivos para forçar os scripts a serem executados em série no sistema. Isso é útil se você não quiser que dois scripts do mesmo tipo funcionem nos mesmos arquivos. Caso contrário, os dois scripts interfeririam entre si e possivelmente danificariam os dados.
#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>&-
Use o rebanho funcionalmente definindo bloqueio e desbloqueio
Você também pode agrupar essa lógica de bloqueio / desbloqueio em funções reutilizáveis. O seguinte trap
shell incorporado liberará automaticamente o bloqueio de arquivo quando o script sair (erro ou êxito). trap
ajuda a limpar os bloqueios de arquivos. O caminho /tmp/file.lock
deve ser um caminho codificado para que vários scripts possam tentar travá-lo.
# 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>&-
}
A unlock
lógica acima é excluir o arquivo antes do bloqueio ser liberado. Dessa forma, ele limpa o arquivo de bloqueio. Como o arquivo foi excluído, outra instância deste programa pode obter o bloqueio do arquivo.
Uso de funções de bloqueio e desbloqueio em scripts
Você pode usá-lo em seus scripts como no exemplo a seguir.
#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
Se você deseja que seu código aguarde até que seja capaz de bloquear, você pode ajustar o script como:
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