Запускать Cronjob каждую ночь между 3-6 часами, но только один раз
Я хочу запускать cronjob ежедневно в определенный промежуток времени, но только один раз за этот период. Как это возможно?
Я вижу возможность в анакроне, но не знаю, как настроить такой сценарий.
3 ответа
Вы можете поместить свой cronjob в /etc/cron.daily/
и он будет автоматически работать в этот период времени.
Редактировать:
Извините, я ссылался на старую установку Debian, где anacron
не был установлен по умолчанию. В таком случае /etc/cron.daily/
был казнен /etc/crontab
в 6:25. Но более новые установки Debian (как и Ubuntu) устанавливаются anacron
по умолчанию и так /etc/cron.daily/
будет выполнен /etc/anacrontab
пять минут спустя anacron
был начат или каждый новый день.
Для достижения вашего графика (из комментариев) вы можете установить cronjob, который будет, например, каждые 10 минут между 3-6, либо anacron
это позаботится о том, чтобы задание резервного копирования запускалось только один раз, или вы можете написать собственный скрипт управления.
1. Альтернатива: анакрон
mkdir ~/.local/share/anacron_spool
echo "1 0 backup.daily /path/to/backup.sh" > ~/.config/anacrontab
(crontab -l; echo "*/10 3-6 * * * /usr/sbin/anacron -s -t $HOME/.config/anacrontab -S $HOME/.local/share/anacron_spool") | crontab -
Это сделает анакрон для сериализации (-s
) выполнить все задания, определенные в ~/.config/anacrontab
, Потому что по умолчанию только root имеет право на запись в /var/spool/anacron/
где хранятся метки времени, мы используем специальный каталог (-S
). Если все работы будут выполнены на сегодня, Anacron выйдет.
2. Альтернатива: пользовательский скрипт управления
Откройте редактор (например, sudo nano /usr/local/bin/run_once_a_day.sh
) и вставьте это:
#!/bin/bash
SPOOL="$HOME/.local/share/run_once_spool/"
if [ $# != 2 ]; then
echo "Usage: $(basename $0) <job-identifier> <command>"
exit 1
fi
if [ ! -d $SPOOL ]; then
mkdir $SPOOL
fi
if [ -e ${SPOOL}${1} ]; then
last_run=$(cat ${SPOOL}${1})
else
last_run=0
fi
today=$(date +%Y%m%d)
if [ $last_run != $today ]; then
$2
echo $today > ${SPOOL}${1}
fi
Нажмите CTRL+O для сохранения и CTRL+X для выхода. Сделайте его исполняемым и добавьте cronjob, который будет периодически запускаться с:
sudo chmod 755 !$
(crontab -l; echo "*/10 3-6 * * * /usr/local/bin/run_once_a_day.sh backup.daily /path/to/backup.sh") | crontab -
Я думаю, что самый простой обходной путь - это вызывать скрипт-обертку каждые N минут в течение интервала, но он начинается с проверки наличия файла "locker", который он создает при выполнении.
#!/bin/bash
[[ -f /dev/shm/cron-once-script-lock ]] && exit 0
touch /dev/shm/cron-once-script-lock
actualcronjob.sh # or whatever non-script command it may be
# end of wrapper script
И линия cron будет выглядеть так:
*/10 3-6 * * * /wherever/the/script/is/wrapper-script.sh
Или возможно
*/10 3-6 * * * bash /wherever/the/script/is/wrapper-script.sh
Единственное предостережение в том, что cron работает в ограниченной "среде", и вам может понадобиться экспортировать переменные окружения и тому подобное, но это совсем другая тема.
Задание cron будет запускаться каждый раз только один раз по заданному расписанию / времени. Таким образом, если вы установите задание cron, в которое время вы хотите от 3 до 6, оно будет выполняться только один раз в указанное время. Только один раз и никогда больше, чем один раз!
Смотрите больше объяснений и несколько примеров на: http://en.wikipedia.org/wiki/Cron