Приклад: використання 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