Мы хотели бы использовать cronjob для создания резервной копии базы данных.
Резервное копирование должно происходить каждые два дня. Можно ли использовать следующий cron-entry?
Если это неправильно, сообщите мне правильную команду для установки cron в течение 2 дней.
Ответ 1
От здесь:
Cron также поддерживает значения "step".
Значение */2
в поле dom означает, что команда запускается каждые два дня и аналогично, */5
в поле часов будет означать, что команда запускается каждые 5 ч. например.
* 12 10-16/2 * * root backup.sh
совпадает с:
* 12 10,12,14,16 * * root backup.sh
Итак, я думаю, что вы хотите 0 0 */2 * *
.
То, что у вас есть (0 0 2 * *
), будет запускать команду во 2-м месяце в полночь, каждый месяц.
p.s. У вас, кажется, есть дополнительная звездочка в вашем ответе. Формат должен быть:
minute hour dom month dow user cmd
Таким образом, ваша дополнительная звездочка будет в поле user
. Это предназначено?
Ответ 2
Отказ от ответственности: это копия моего deleted
ответа здесь. Я верю, что этот вопрос более канонический, и мой ответ лучше подходит здесь.
Есть два способа интерпретировать этот вопрос.
- Я хотел бы запланировать работу cron каждый второй день месяца.
- Я хотел бы запланировать работу cron каждые два дня.
Это два совершенно разных случая из-за количества дней в месяц.
Я хотел бы запланировать cronjob каждый второй день месяца.
Для этого мы используем комбинацию определения диапазона и значения шага:
man 5 crontab
: значения шага могут использоваться в сочетании с диапазонами. После диапазона с /<number>
указывает пропускание значения числа в диапазоне. Например, 0-23/2
можно использовать в поле "часы", чтобы указать выполнение команды на каждый другой час (альтернатива в стандарте V7 составляет 0,2,4,6,8,10,12,14,16,18,20,22
). Значения шагов также разрешены после звездочки, поэтому, если задание должно выполняться каждые два часа, вы можете использовать */2
.
См. Следующие примеры:
# Example of job definition:
# .-------------------- minute (0 - 59)
# | .----------------- hour (0 - 23)
# | | .-------------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 */2 * * command1
0 0 2-31/2 * * command2
* * */2 * * command3
-
command1
будет выполняться в 00:00 в каждый нечетный день (диапазон по умолчанию с шагом 2, т.е. 1,3,5,7,..., 31) -
command2
будет выполняться в 00:00 в каждый четный день (т.е. 2,4,6,8,..., 30) -
command3
часто ошибается. Это будет выполняться каждую минуту каждого нечетного дня.
Примечание. Следует понимать, что в этом подходе command1
будет работать как с 31 января, так и с 1 февраля (2 последовательных дня)
Примечание. Следует понимать, что в этом подходе command2
пропустит как 31 января, так и 1 февраля и будет работать только через 3 дня.
Я хотел бы запланировать cronjob каждый второй день (начиная с дня X)
Здесь он становится интереснее. В приведенных выше заметках была отмечена проблема с месяцами с нечетным количеством дней.
Быстрый способ подумать о том, чтобы оценить день года:
% date -d "2018-01-31" '+%j'
031
% date -d "2018-02-01" '+%j'
032
и вы можете легко исследовать, является ли это нечетным или четным числом. Однако при этом у вас снова возникает проблема 31 декабря и 1 января в общий год (365 дней, високосные годы - 366 дней). Это можно решить, если у вас есть непрерывный счетчик с данного дня. Введите 1970-01-01 00:00:00 UTC
времени UNIX, общее количество секунд с 1970-01-01 00:00:00 UTC
.
% date -d "2018-12-31" '+%s %j'
1546214400 365
% date -d "2019-01-01" '+%s %j'
1546300800 001
% date -d "2019-12-31" '+%s %j'
1577750400 365
% date -d "2020-01-01" '+%s %j'
1577836800 001
Чтобы cronjob запускал command4
только каждый второй день в 00:00
и command5
каждый третий день в 00:00
начиная с "2018-03-14", crontab выглядел бы так:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 * * * daytestcmd 2 && command4
0 0 * * * daytestcmd 3 20180314 && command5
с daytestcmd
определяется как
#!/usr/bin/env bash
# get start time in seconds
start=$(date -d "${2:[email protected]}" '+%s')
# get current time in seconds
now=$(date '+%s')
# get the amount of days (86400 seconds per day)
days=$(( (now-start) /86400 ))
# set the modulo
modulo=$1
# do the test
(( days >= 0 )) && (( days % modulo == 0))
Примечание. Время UNIX дается в формате UTC. Если ваш cron работает в другой временной зоне, на которую влияет летнее время, рекомендуется не запускать команду между 2 и 3 часами. Это может пропустить команду или выполнить команду дважды (в зависимости от того, будет ли время переходить вперед или назад)
Примечание. Время UNIX не зависит от секунд прыжка