Запускать 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

Другие вопросы по тегам