Cronjob за первый день месяца кроме воскресенья

2771
Alexander Kim

У меня есть такая запись в моем crontab:

0 0 1-2 * 1-6

Это правильно, что он будет работать в 00:00, 1-го или 2-го числа месяца с понедельника по субботу? Например, если 1-й день будет воскресеньем, он не будет работать, верно? Но вместо этого он будет запускать cronjob во 2-й день месяца, потому что это не будет воскресенье.

2

1 ответ на вопрос

5
jaume

If the first day of the month is a Sunday it will indeed run.

The reason is that the two conditions "day of month" (third field) and "day of week" (fifth field) are not connected with an AND (both must occur) but with an OR (either one must occur). From man 5 crontab:

Note: The day of a command's execution can be specified by two fields -- day of month, and day of week. If both fields are restricted (ie, are not *), the command will be run when either field matches the current time. For example, ``30 4 1,15 * 5'' would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.

So your cronjob will run at midnight every 1st and 2nd of the month and additionally every Mon, Tue, Wed, Thu, Fri and Sat of the month.

If you need to run the command only once in a month but not on Sunday, as you write in your comment, you must check the date in the command itself.

These are the conditions to run the command:

IF (date is 1st day of month AND date is not Sunday) OR (date is 2nd day of month AND yesterday was Sunday) THEN run command 

You could write two cronjobs:

0 0 1 * * test $(date +\%u) -eq 7 || echo "today's the 1st day of the month but not Sun" 0 0 2 * * test $(date +\%u) -eq 1 && echo "today's Mon (=yesterday was Sun) and the 2nd day of the month" 

The first cronjob will run every 1st day of the month at midnight:

  • date +%u returns an integer where 1 is Mon, 2 is Tue, etc. (the ‘%’ needs to be escaped in a crontab).

  • test checks whether $(date +%u1) equals 7 (Sunday).

  • || is the OR boolean operator, it reacts to the return value of the previous command. If test returns FALSE then the rest of the command is run.

The second cronjob will run every 2nd day of the month at midnight:

  • Again, date +%u returns an integer where 1 is Mon, 2 is Tue, etc.

  • test checks whether $(date +%u1) equals 1 (Monday).

  • && is the AND boolean operator, if test returns TRUE then the rest of the command is run.

Спасибо, что означает test в "test $ (date +% u) -eq 7"? Alexander Kim 10 лет назад 0
@ Heihachi Я отредактировал свой ответ, чтобы прояснить это. Смотрите `man test` для получения дополнительной информации. jaume 10 лет назад 0
Понял. Но если 1-й и 2-й день месяца - понедельник и вторник, cron будет запускаться 2 раза в месяц. Мне нужно выполнять команду только один раз в месяц, но не в воскресенье. Лучшее место для этого есть в самом bash-скрипте? Alexander Kim 10 лет назад 0
Спасибо за разъяснение этого. Я отредактировал свой ответ, я предлагаю вам написать два cronjobs (вы также можете написать один, но оператор `test` будет сложным). jaume 10 лет назад 0

Похожие вопросы