Запускать скрипт через cron каждую неделю

12

Я провел немало исследований о том, как это сделать, и вижу, что в cron нет прямого способа запустить работу, скажем, каждый второй четверг.

Прямо сейчас я склоняюсь к созданию сценария, который будет запускаться каждую неделю и будет касаться файла «flag» при его запуске , и, если он запущен и файл уже существует, удалить файл (а не выполнить раз в две недели).

У меня вопрос, есть ли какой-нибудь другой более изящный или более простой способ для достижения этой цели сценария действий bash, запускаемого раз в две недели автоматически?

Благодарность!

dmkmills
источник
1
Вместо файла флага вы можете использовать номера недель ISO. (Например,% V. Strftime.)
@ Роджер: Я полагаю, вы имеете в виду в условном в сценарии.
Приостановлено до дальнейшего уведомления.
@ Денис: Не обязательно (например, посмотрите, как мой ответ проверяет вне сценария), но моя главная мысль в том, что это будет намного проще и не требует состояния в файловой системе. Однако я понял, что у него есть тот же недостаток, что и у контрольного дня месяца: у некоторых лет 53 недели, у некоторых 52.

Ответы:

11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

Я использовал bash для своей математики, потому что я ленивый; переключи что хочешь. Я пользуюсь тем, что 1 января 1970 года был четвергом; для других дней недели вам придется применить смещение. Крону нужны знаки процента.

Быстрая проверка:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

Примечание. Я выбрал случайное время, чтобы показать, что это будет работать, если оно выполняется в любое время в четверг, и выбрал даты, которые пересекают границы года, плюс месяцы с 4 и 5 четвергами.

Выход:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

источник
2
Секунды с начала эпохи по UTC, а cron работает по местному времени. Если часовой пояс вашей системы не UTC, это может привести к путанице. («Почему это не работает? О, это уже пятница в UTC»). Существование летнего времени делает работу вокруг этого намного более сложной (хотя и не невозможной, поскольку date cal сообщает вам текущее смещение UTC)
derobert
5

Одним из способов может быть использование atутилиты, если вы работаете в Linux. Вы можете поместить это в конец вашего скрипта:

at X + 2 weeks -f myscript

где X - время, в которое вы хотите запустить свой скрипт. Для инициализации просто позвоните atв тот момент, когда вы хотите запустить его в первый раз, а затем вышеприведенный оператор продолжает обновлять ваш запланированный вызов.

gvkv
источник
Если это будет долгосрочным решением, я бы не рекомендовал запускать его, хотя в нем я бы создал функцию в сценарии, которая бы решала, нужно ли ее запускать
Paul
3

Если вы можете использовать anacronв системе, все будет гораздо проще. Для использования у anacronвас должна быть установлена ​​программа, а также вы должны иметь root-доступ. Он не работает на старых системах (например, RHEL 5.x), старые версии ancron работают ТОЛЬКО при загрузке. Он работает с более новыми системами (например, RHEL 6.x).

С его помощью anacronможно более гибко планировать задания, например, запускать задание X раз в неделю. Также anacronзапускает задания, когда компьютер становится доступным, то есть вам не нужно учитывать, когда система работает или не работает.

Чтобы запускать скрипт каждую вторую неделю, вы должны добавить строку, похожую на следующую, в / etc / anacrontab:

14 5 myScript script.sh

Взгляните на справочную страницу для деталей.

memin
источник
Использование anacron, безусловно, является самым чистым решением IMO (если оно не имеет нежелательных последствий для некоторых людей).
JanC
0

Я не уверен, есть ли более элегантный способ определять каждую вторую неделю, но это может сработать для вас.

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

Это запустит сценарий в 6:00 утра в первый и третий четверги месяца.

pferate
источник
2
Это будет пропускать неделю, если есть месяц с 3 четвергами.
Дэвид З
1
Есть ли месяц, который имеет только 3 четверга? Хотя я вижу, как пропустить неделю, если есть 5 четвергов. Он может быть обновлен до 1-7,15-21,29-31, но тогда он будет работать вплотную, если будут какие-либо совпадения для последнего сета ...
pferate
1
Под 3 четвергами вы имели в виду 3 четверга, что сценарий будет запущен, а не 3 полных четверга? Возможно, я неправильно прочитал это в первый раз.
pferate
0

Я запускал его каждую неделю, и мне нужно было проверить сценарий, чтобы узнать, является ли номер недели нечетным: если да, выйдите.

Надо еще немного подумать, чтобы работать с декабря по январь.

Возможно, сценарий установил файл флага «последний успешный запуск». Когда скрипт запустится, проверьте, что файл флага последний раз изменялся 14 дней назад.

Гленн Джекман
источник