Запускать несколько заданий cron, где одно задание занимает много времени

16

У меня есть следующий общий вопрос относительно рабочих мест cron.

Предположим, у меня есть следующее в моем crontab:

* 10 * * * * someScript.sh
* 11 * * * * someScript2.sh
30 11 */2 * * someScript3.sh  <-- Takes a long time let's say 36 hours.
* 12 * * * someScript4.sh

Достаточно ли умен, чтобы запустить оставшиеся задания в подходящее время? Например, длинный скрипт не должен завершаться?

Кроме того, что произойдет, если начальный длинный скрипт все еще выполняется и его снова вызывает cron?

Спасибо!

user1357015
источник
Крону все равно, как долго выполняются задания. он будет запускать дополнительные копии.
Джефф Шаллер
Пожалуйста, убедитесь, что ваши вопросы отформатированы правильно.
Брэм

Ответы:

31

Каждое задание cron выполняется независимо от других заданий, которые вы могли указать. Это означает, что ваш долгоживущий скрипт не будет препятствовать выполнению других заданий в указанное время.

Если какой-либо из ваших сценариев все еще выполняется в следующем запланированном интервале cron, то будет выполнен другой параллельный экземпляр вашего сценария.

Это может иметь непредвиденные последствия в зависимости от того, что делает ваш скрипт. Я бы порекомендовал прочитать статью в Википедии о блокировке файлов , в частности, раздел о блокировке файлов . Файл блокировки - это простой механизм, который сигнализирует о том, что ресурс - в вашем случае someScript3.shсценарий - в настоящий момент «заблокирован» (т.е. используется) и не должен выполняться снова, пока файл блокировки не будет удален.

Посмотрите ответы на следующий вопрос для получения подробной информации о способах реализации файла блокировки в вашем скрипте:

soulcake
источник
8

Не уверен, что вы подразумеваете под подходящим временем. Cron начнет работу в то время, когда это запланировано. Он не проверяет другие запланированные задания или другие экземпляры задания.

Таким образом, все заданные вами действительные задания будут запущены в указанное время. Любое задание, которое выполняется дольше указанного интервала, будет запущено несколько раз. Тот, кто написал задание, обязан не допустить его многократного запуска, если это требуется. Например, проверяя файл блокировки или файл PID или что-то.

Существуют очевидные ограничения на количество процессов, которые могут выполняться параллельно, но они не являются специфичными для cron.

Брэм
источник
6

В дополнение к другим ответам, особенно по ссылке, опубликованной @soulcake: если вы запланируете длительную команду с слишком коротким интервалом, cron с удовольствием выполнит вторую перед завершением первой (если в команде не реализован какой-либо мьютекс) ,

Это часто замедляет исходную команду еще больше, приводя к тому, что другой экземпляр запускается до завершения предыдущих и т. Д. Или это может быть нежелательно по другим причинам.

Общий способ предотвратить это - выполнить команду с защитой, которая гарантирует, что предыдущая команда не выполняется. Например:

10 * * * * pgrep my_slow_command >/dev/null || /usr/local/bin/my_slow_command

Убедитесь, что pgrep совпадает с именем команды при запуске, например, скрипты python имеют имя python в качестве имени исполняемого файла, что, вероятно, недостаточно конкретно, и вам также нужно будет сопоставить имя скрипта python.

10 * * * * pgrep -f my_script.py || /usr/local/bin/my_script.py

(хотя pgrep без опции '-f' соответствует именам скриптов bash)

Если по какой-то причине вы не можете использовать pgrep:

10 * * * * ps ax | grep [m]y_command || /usr/local/bin/my_command

Скобки используются, чтобы избежать совпадения с самой командой grep.

Edheldil
источник
0

Я использую flock.

* * * * * exec flock --nonblock .ws_client.lock -c ws_client.py >& /tmp/ws_client.out
JohnMudd
источник