Задания Cron и случайное время в течение заданных часов - PullRequest
81 голосов
/ 29 января 2012

Мне нужна возможность запуска сценария PHP 20 раз в день в совершенно случайное время.Я также хочу, чтобы он работал только с 9:00 до 23:00.

Ответы [ 9 ]

117 голосов
/ 30 апреля 2013

Да, да, вопрос старше года, но, может быть, я могу добавить что-нибудь полезное:

Как создать что-то со случайным смещением 20 раз в день с 9:00 до 23:00?Это немного сложно в cron, потому что вы делите 14 часов на 20 раз выполнения.Мне не очень нравятся другие ответы, потому что они требуют написания скрипта bash wrapper для вашего php-скрипта.

Однако, если вы позволите мне, я могу уменьшить время и частоту до 13 раз между8:30 и 23:09, это может помочь, и все в пределах вашего crontab:

30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php

$ {RANDOM: 3: 2} использует $ RANDOM от bash, о котором упоминали другие люди выше, но добавляет срез массива bash.Поскольку переменные bash не типизированы, псевдослучайное 16-разрядное число со знаком усекается до первых 2 из его 5 десятичных цифр, что дает вам краткую однострочную строку для отсрочки выполнения cronjob между 10 и 99 минутами (хотя распределение смещено в сторонуС 10 по 32).

Следующее может также сработать для вас, но я обнаружил, что оно «менее случайное» по какой-то причине (возможно, закон Бенфорда срабатывает путем модуляции псевдослучайных чисел.не знаю, я завалил математику ... вините в bash!):

30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php

Вам нужно отобразить модуль как '\%' выше, потому что cron (ну, по крайней мере, Linux 'vixie-cron')завершает строку, когда встречает неэкранированный '%'.

Возможно, вы могли бы получить оставшиеся 7 выполнений сценария, добавив еще одну строку с другим 7-часовым диапазоном.Или ослабьте ограничение на бег с 3:00 до 23:00.

51 голосов
/ 26 марта 2015

Поэтому я использую следующее для запуска команды между 1:00 и 330:00

0 1 * * * perl -le 'sleep rand 9000' && *command goes here*

, которая заботилась о моих случайных потребностях в себеЭто 9000 секунд == 150 минут == 2,5 часа

29 голосов
/ 29 января 2012

Если я понимаю, что вы ищете, вам нужно сделать что-то немного грязное, например, иметь работу cron, которая запускает скрипт bash, который рандомизирует время выполнения ... Что-то вроде этого:

crontab:

0 9 * * * /path/to/bashscript

и в / path / to / bashscript:

#!/bin/bash

maxdelay=$((14*60))  # 14 hours from 9am to 11pm, converted to minutes
for ((i=1; i<=20; i++)); do
    delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs
    (sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script
done

Несколько замечаний: этот подход немного расточителен, так как запускает 20 фонпроцессы в 9:00, каждый из которых ожидает в течение произвольного количества минут (до 14 часов, то есть до 11 вечера), затем запускает скрипт php и завершает работу.Кроме того, поскольку он использует случайное количество минут (не секунд), время начала не так случайно, как могло бы быть.Но $ RANDOM поднимается только до 32 767, и между 9:00 и 23:00 есть 50 400 секунд, было бы немного сложнее также рандомизировать секунды.Наконец, поскольку время начала является случайным и не зависит друг от друга, возможно (но не очень вероятно), что два или более экземпляров сценария будут запущены одновременно.

16 голосов
/ 15 января 2016

Cron предлагает переменную RANDOM_DELAY. Подробнее см. crontab(5).

Переменная RANDOM_DELAY позволяет задерживать запуск заданий на случайную величину минуты с верхним пределом, заданным переменной.

Это обычно наблюдается в anacron заданиях, но также может быть полезно в crontab.

Возможно, вам следует быть осторожным с этим, если у вас есть задания, которые работают нормально (минутная) гранулярность и другие грубые.

6 голосов
/ 30 января 2012

Моей первой мыслью было бы создать одно задание cron, запустив 20 случайно назначенных заданий.Утилита at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) используется для выполнения команд в указанное время.

4 голосов
/ 14 января 2016

Я использовал sleep $(( 1$(date +%N) % 60 )) ; dostuffs (совместимо с bash & sh)

Префикс 1 используется для принудительной интерпретации даты без базы 8 +% N (например, 00551454)

Не забудьте экранировать% используя \% в файле crontab

* * * * *  nobody  sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs 
1 голос
/ 18 декабря 2017

at -f [file] [timespec]

или

echo [command] | at [timespec]

или

at [timespec] ... и интерактивные спецификации, такие как scriptзапись.

Команда

При выполнении текста введите stdin или в файле, указанном -f [file].

Timespec

Вот грамматика [timespec] .Это может быть что-то вроде:

  • 24-часовое время как 4-значный int, например, 0100, 2359, 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Если вы явно указываете часовой пояс, некоторые версии спецификации времени могут разрешить только UTC для необязательного аргумента часового пояса.

Пример

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Попробуйте ...

Вы можете проверить синтаксический анализ bash, предварительно ожидая echo и экранирование | (pipe).

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Чтобы просмотреть запланированные задания, используйте atq и содержимое задания (средаvars, setup и command / script) с at -c [jobid].

Note

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

0 голосов
/ 11 апреля 2019

Решение al-x не работает для меня, так как команды crontab не выполняются в bash, но в sh я думаюЧто работает:

30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
0 голосов
/ 20 февраля 2018

Для тех, кто погуглил здесь:

Если вы используете anacron (настольный компьютер и ноутбук Ubuntu), вы можете отредактировать

/etc/anacrontab

и добавить

RANDOM_DELAY=XX 

Где XX - количество минут, которое вы хотите отложить на базовое задание.

Anacron похож на cron, но не ожидает, что ваш компьютер будет работать круглосуточно (как наши ноутбуки), и будет запускать сценарии, которые он выполняет.пропустил, потому что система не работает.

...