Назад | Перейти на главную страницу

Запускать cronjob каждый день, кроме первого дня месяца

Я пытаюсь:

  1. запустить задание A в первый день месяца: 0 0 1 * *
  2. выполнить задание B в другие дни месяца: 0 0 2-31 *?

Vixie cron в Ubuntu 14.02 LTS отказывается от второго синтаксиса, хотя, согласно Википедия и официальные спецификации:

«crontab», выпуск 7 базовых спецификаций Open Group - IEEE Std 1003.1, издание 2013 г., The Open Group, 2013 г., получено 18 мая 2015 г.

Согласно приведенным выше ссылкам, синтаксис 0 0 2-31 * * будет запускать задание каждый день месяца, поскольку третье и пятое поля обрабатываются как операторы ИЛИ условия выполнения.

Вы должны использовать *, а не ? (что неверно).

На странице Википедии отмечается, что ? это нестандартное расширение, используемое только nnCron, который вы не используете.

В любом случае, если день недели установлен на * и указывается день месяца, тогда день недели игнорируется. Спецификация IEEE 1003.1, на которую вы ссылаетесь на самом деле заявляет это, объясняя, как эти поля взаимодействуют:

Если месяц или день месяца указаны как элемент или список, но день недели - это <asterisk>, в полях месяца и дня месяца должны быть указаны совпадающие дни. Если и месяц, и день месяца указаны как <asterisk>, но день недели является элементом или списком, то совпадают только указанные дни недели. Наконец, если месяц или день месяца указан как элемент или список, а день недели также указан как элемент или список, то любой день, соответствующий либо месяцу и дню месяца, либо дню недели, должны быть сопоставлены.

Таким образом, правильный формат - это как раз логичный:

0 0 1 * * echo First of the month
0 0 2-31 * * echo Not the first of the month

Вы можете использовать дату:

0 0 * * * [ $(date +\%d) -eq 1 ] && echo I will run on the 1st
0 0 * * * [ $(date +\%d) -ne 1 ] && echo I will run on all other days

Если ваш crond не позволяет вам указывать разные даты, оберните ваши скрипты небольшим сценарием оболочки.

#!/bin/bash
if [[ `date +%d` -eq 01  ]]
        then
                /path/to/script_a
        else
                /path/to/script_b
fi

Запускайте сценарий каждый день и позвольте ему решать, какой из ваших сценариев запускать.