Мне нужна возможность запускать PHP-скрипт 20 раз в день в совершенно произвольное время. Я также хочу, чтобы он работал только с 9 до 23 часов.
Я знаком с созданием рабочих мест cron в Linux.
Мне нужна возможность запускать PHP-скрипт 20 раз в день в совершенно произвольное время. Я также хочу, чтобы он работал только с 9 до 23 часов.
Я знаком с созданием рабочих мест cron в Linux.
Ответы:
Если я понимаю, что вы ищете, вам нужно сделать что-то немного беспорядочное, например, создать задание cron, которое запускает сценарий bash, который рандомизирует время выполнения ... Примерно так:
crontab:
0 9 * * * /path/to/bashscript
и в / путь / к / 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 утра, каждый из которых ждет случайное количество минут (до 14 часов, т.е. 11 вечера), затем запускает скрипт php и выходы. Кроме того, поскольку он использует случайное количество минут (не секунд), время начала не такое уж случайное, как могло бы быть. Но $ RANDOM увеличивается только до 32 767, а между 9 утра и 11 вечера есть 50 400 секунд, было бы немного сложнее рандомизировать секунды. Наконец, поскольку время запуска случайное и не зависит друг от друга, возможно (но маловероятно), что два или более экземпляра скрипта будут запущены одновременно.
((maxdelay = 14 * 60))
или ((delay = $RANDOM % maxdelay))
). sleep
Аргумент еще должен быть путь у вас есть (хотя вы можете добавить пробелы, если это необходимо).
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Да, да, этому вопросу больше года, но, может быть, я могу добавить что-нибудь полезное:
Как выполнить cron с произвольным смещением 20 раз в день с 9 утра до 11 вечера? В cron это довольно сложно, потому что вы делите 14 часов на 20 времени выполнения. Мне не очень нравятся другие ответы, потому что они требуют написания сценария-оболочки bash для вашего 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).
Следующее также может сработать для вас, но я обнаружил, что он по какой-то причине «менее случайен» (возможно, закон Бенфорда запускается путем модуляции псевдослучайных чисел. Эй, я не знаю, я завалил математику ... на баш!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Вы должны отобразить модуль как '\%' выше, потому что cron (ну, по крайней мере, Linux 'vixie-cron') завершает строку, когда встречает неэкранированный '%'.
Возможно, вы могли бы получить оставшиеся 7 исполнений скрипта, добавив еще одну строку с другим 7-часовым диапазоном. Или ослабьте свое ограничение, чтобы бегать с 3 утра до 11 вечера.
$[(RANDOM/368)+10]
?
$((RANDOM % 90 + 10))
Тест:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
$RANDOM
: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
.
crontab
используется , bash
прежде чем использовать $RANDOM
. Если у вас есть vixie-cron
(похоже, мой случай на Ubuntu), то вы можете добавить SHELL=/bin/bash
в начало. Здесь есть другие альтернативы для других версий cron: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
пожалуйста, помощь
Итак, я использую следующее для запуска команды между 01:00 и 330:00.
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Это позаботилось о моих случайных потребностях. Это 9000 секунд == 150 минут == 2,5 часа
Cron предлагает RANDOM_DELAY
переменную. Подробнее crontab(5)
см.
Переменная RANDOM_DELAY позволяет задерживать запуск задания на произвольное количество минут с верхним пределом, указанным переменной.
Это часто встречается на anacron
рабочих местах, но также может быть полезно в crontab
.
Вам может потребоваться быть осторожным с этим, если у вас есть некоторые задания, которые выполняются с мелкой (минутной) детализацией, а другие - с грубой.
RANDOM_DELAY
он устанавливается один раз и остается постоянным в течение всего времени работы демона.
RANDOM_DELAY
Флаг особенность cronie-crond в то время как Ubuntu , кажется, работает в vixie-cron
котором отсутствует этот флаг.
Моя первая мысль заключалась в том, чтобы создать одно задание cron, запускающее 20 заданий, случайно запланированных для этого. at
Полезности (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) используются для выполнения команд в заданное время.
В итоге я использовал sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(совместим с bash & sh)
Префикс 1 означает, что дата не интерпретируется по основанию 8 +% N (например, 00551454).
Не забудьте экранировать%, используя \% в файле crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
date
(что вы, вероятно, делаете на большинстве Linux, но не на Busybox, стандартной MacOS или различных других платформах, основанных на BSD).
Решение al-x не работает для меня, поскольку команды crontab выполняются не в bash, а в sh, я думаю. Что работает:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
является устаревшим синтаксисом с тех пор, как он вернулся; для чего-либо из этого тысячелетия вы бы предпочли $((RANDOM\%90))m
POSIX-совместимый синтаксис (но, конечно, RANDOM
по-прежнему только Bash).
at -f [file] [timespec]
или
echo [command] | at [timespec]
или
at [timespec]
... и интерактивная спецификация, такая как script
запись.
При запуске текст предоставляется на стандартный ввод или в файл, указанный в -f [file]
.
Вот [timespec]
грамматика . Это может быть что-то вроде:
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
и содержимое задания (переменные среды, настройки и команды / скрипты) с at -c [jobid]
.
Система является частью cron, и интерактивное приглашение фактически фиксирует все текущее состояние вашей оболочки, поэтому вы можете запускать команды без указания абсолютных путей.
Для тех, кто гуглил путь сюда:
Если вы используете Anacron (настольный компьютер и ноутбук Ubuntu), вы можете редактировать
/etc/anacrontab
и добавить
RANDOM_DELAY=XX
Где XX - это количество минут, на которое вы хотите отложить базовое задание.
Anacron похож на cron, но он не ожидает, что ваш компьютер будет работать круглосуточно (как наши ноутбуки), и будет запускать сценарии, которые он пропустил из-за того, что система вышла из строя.
В этом примере вы можете попробовать использовать случайное время перед выполнением команды:
#!/bin/bash
# start time
date +"%H:%M:%S"
# sleep for 5 seconds
sleep $(shuf -i 1-25 -n 1)
# end time
date +"%H:%M:%S"
А как насчет создания сценария, который каждый день перезаписывает crontab?
Я понимаю, что это старый поток, но я хочу добавить одну вещь, связанную со случайными значениями, которую я часто использую. Вместо использования переменной $ RANDOM с фиксированным и ограниченным диапазоном я часто делаю случайные значения произвольного диапазона в оболочке с помощью
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
так что вы можете сделать, например,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
и преодолеть некоторые ограничения, которые обсуждались в этой ветке.
~$info dd
и я могу понять, что происходит с левой стороны |
, но не могу разобрать правую сторону. Итак, для меня и других, интересующихся overcoming some restrictions
генерацией случайных значений, почему бы не уделить время объяснению RHS и сделать более убедительный аргумент в пользу использования вашего подхода. Глубина объяснения позволяет людям чувствовать себя комфортно как с процессом, который вы предлагаете, так и с его преимуществами. Спасибо.