Часто люди бездумно засовывают в крон запуск долгоиграющих скриптов и потом ловят кучу багов.
К примеру некий скрипт запускается в кроне каждый час. В какой-то момент, время выполнения скрипта начинает составлять 70 и более минут. Соответственно следующий джоб через 60 минут запустит еще одну копию этого скрипта. И понеслась 3.14зда по кочкам.
Я ловил у ребят подобные перлы, когда сервер просто раком встает, а в фоне крутятся 100500 процессов, которые насилуют mysql как портовую шлюху, вдоль и поперек.
На такие случаи необходимо проверять запущен ли скрипт в данный момент. И если запущен, то при повторном запуске - ничего не делать.
Как такое реализовать? В бест-практиках это реализуется через lock файлы. Для удобства работы с lock файлами, в linux есть коробочный вариант утилиты, которая называется flock.
flock — утилита, которая позволяет использовать лок-файл для предотвращения запуска копии процесса (вашего скрипта, крона или чего-то еще). Например, используя cron нужно быть уверенным, что предыдущий запуск вашего скрипта уже завершен.
Пишем обработчик:
Как только скрипт завершит работу, ты сможешь запустить его повторно.
Сначала создается lock файл если его нет, а далее начинается магия с дескрипторами и логикой.
Вместо sleep можно вставить запуск функции типа main() где и будет основная логика скрипта. Либо вообще через source (или точку) заинклудить свой скрипт. То есть можно сделать универсальную штуку, чтобы в каждый скрипт не пихать flock.
Делаешь один обработчик и передаешь ему параметром путь до скрипта + путь до lock файла. А обработчик через source подгружает уже полезную нагрузку.
Моё решение возможно не самое изящное, но рабочее. Изучай. Слышал что такое можно провернуть каким-то образом через сокеты, но особо не вникал. Если в комментах поделишься, будет очень полезно. Спасибо!
tags: #linux #bash #utils
—
💩 @bashdays
К примеру некий скрипт запускается в кроне каждый час. В какой-то момент, время выполнения скрипта начинает составлять 70 и более минут. Соответственно следующий джоб через 60 минут запустит еще одну копию этого скрипта. И понеслась 3.14зда по кочкам.
Я ловил у ребят подобные перлы, когда сервер просто раком встает, а в фоне крутятся 100500 процессов, которые насилуют mysql как портовую шлюху, вдоль и поперек.
На такие случаи необходимо проверять запущен ли скрипт в данный момент. И если запущен, то при повторном запуске - ничего не делать.
Как такое реализовать? В бест-практиках это реализуется через lock файлы. Для удобства работы с lock файлами, в linux есть коробочный вариант утилиты, которая называется flock.
flock — утилита, которая позволяет использовать лок-файл для предотвращения запуска копии процесса (вашего скрипта, крона или чего-то еще). Например, используя cron нужно быть уверенным, что предыдущий запуск вашего скрипта уже завершен.
Пишем обработчик:
#!/bin/bashЗапускаем скрипт. Ничего полезного он не сделает, просто будет висеть 100 секунд. После того как ты запустил этот скрипт, в соседнем терминале попробуй запустить его же параллельно. В ответ ты получишь ожидаемое - Nice try.
lock="/tmp/bashdays.lock"
[[ -f "${lock}" ]] || touch "${lock}"
(
flock -n -o -x ${fd_lock} || { echo 'Nice try' >&2; exit 0; }
sleep 100
) {fd_lock}<"${lock}"
Как только скрипт завершит работу, ты сможешь запустить его повторно.
Сначала создается lock файл если его нет, а далее начинается магия с дескрипторами и логикой.
Вместо sleep можно вставить запуск функции типа main() где и будет основная логика скрипта. Либо вообще через source (или точку) заинклудить свой скрипт. То есть можно сделать универсальную штуку, чтобы в каждый скрипт не пихать flock.
Делаешь один обработчик и передаешь ему параметром путь до скрипта + путь до lock файла. А обработчик через source подгружает уже полезную нагрузку.
Моё решение возможно не самое изящное, но рабочее. Изучай. Слышал что такое можно провернуть каким-то образом через сокеты, но особо не вникал. Если в комментах поделишься, будет очень полезно. Спасибо!
tags: #linux #bash #utils
—