Наверняка сталкивались с такой ситуацией: скрипт ещё работает, а
cron уже запускает следующий экземпляр. Или кто-то решил запустить его вручную, не подозревая, что процесс уже выполняется. В итоге одновременно работают несколько одинаковых процессов. Они начинают менять одни и те же файлы, выполнять одну и ту же работу, создавать лишнюю нагрузку, а иногда ещё и ломать результаты друг друга.Представьте простой пример. Ваш скрипт выполняется 90 секунд, а
cron запускает его каждую минуту:* * * * * /opt/scripts/backup.sh
Уже через минуту появится второй экземпляр, который начнёт работать параллельно с первым. Если выполнение иногда занимает ещё больше времени, количество процессов может быстро вырасти.
Именно для таких случаев в Linux есть
flock. Он использует файловые блокировки ядра и позволяет сказать: пока этот скрипт работает, второй запуск не начинай.Самый простой вариант выглядит так:
flock /tmp/backup.lock /opt/scripts/backup.sh
Первый процесс получит блокировку, а следующий будет ждать, пока она освободится.
Но, честно говоря, для
cron ожидание обычно не имеет смысла. Проще пропустить очередной запуск, чем держать очередь из процессов. Поэтому чаще используют ключ -n:flock -n /tmp/backup.lock /opt/scripts/backup.sh
Если блокировка уже занята, команда сразу завершится с ненулевым кодом, а новый экземпляр просто не запустится.
Именно поэтому в
cron обычно встречается такой вариант:* * * * * /usr/bin/flock -n /var/lock/backup.lock /opt/scripts/backup.sh
Только не забудьте, что пользователь, от имени которого работает
cron, должен иметь доступ к файлу блокировки.Если же вы хотите защитить скрипт независимо от того, как его запускают — через
cron, вручную или из другого скрипта, — блокировку можно поставить прямо внутри него:#!/usr/bin/env bash
exec 200>/var/lock/backup.lock
flock -n 200 || exit 1
echo "Работает только один экземпляр"
Здесь
exec открывает файл блокировки и связывает его с файловым дескриптором 200, а flock устанавливает блокировку именно на этот дескриптор. Пока дескриптор открыт, блокировка остаётся активной. Даже если процесс аварийно завершится, ядро автоматически её снимет, поэтому вечных блокировок здесь не бывает.🔥
flock использует рекомендательные (advisory) блокировки. Это значит, что они работают только между процессами, которые сами используют flock для одного и того же файла блокировки. Если какая-то программа полностью игнорирует механизм блокировок, flock физически её не остановит.🚪 Linux Ready | #практика