Пример: использование flock для принудительного запуска сценариев с блокировками файлов
Одним из примеров является использование блокировки файлов для принудительного запуска сценариев по всей системе. Это полезно, если вы не хотите, чтобы два скрипта одного типа работали с одинаковыми файлами. В противном случае два сценария будут мешать друг другу и, возможно, повреждать данные.
#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>&-
Функционально использовать стадо, определив блокировку и разблокировку
Вы также можете обернуть эту логику блокировки / разблокировки в многократно используемые функции. Следующая trap
встроенная оболочка автоматически снимет блокировку файла при выходе из скрипта (либо ошибка, либо успех). trap
помогает очистить файл блокировки. Путь /tmp/file.lock
должен быть жестко закодированным, чтобы несколько скриптов могли попытаться заблокировать его.
# 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>&-
}
unlock
Логика выше , чтобы удалить файл до снятия блокировки. Таким образом, он очищает файл блокировки. Поскольку файл был удален, другой экземпляр этой программы может получить блокировку файла.
Использование функций блокировки и разблокировки в скриптах
Вы можете использовать его в своих скриптах, как в следующем примере.
#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
Если вы хотите, чтобы ваш код ожидал блокировки, вы можете настроить скрипт следующим образом:
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