Вопрос не очень хорошо поставлен. В конечном итоге вы хотите распределить 20 точек по оси времени между 9 и 11 часами утра. Но есть ли ограничения на минимальную разницу во времени? Разве можно ничего не делать с 9 утра до 10:30? Единственный способ сделать это приемлемо, по мнению Клауса: выберите 20 раз в 09:00, что позволяет выполнить любые ограничения, которые могут у вас возникнуть, а затем запланировать дела с помощью «at».
Дэвид Тонхофер,
Ответы:
38
Если я понимаю, что вы ищете, вам нужно сделать что-то немного беспорядочное, например, создать задание cron, которое запускает сценарий bash, который рандомизирует время выполнения ... Примерно так:
crontab:
09***/path/to/bashscript
и в / путь / к / bashscript:
#!/bin/bash
maxdelay=$((14*60))# 14 hours from 9am to 11pm, converted to minutesfor((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 scriptdone
Несколько примечаний: этот подход немного расточителен, поскольку он запускает 20 фоновых процессов в 9 утра, каждый из которых ждет случайное количество минут (до 14 часов, т.е. 11 вечера), затем запускает скрипт php и выходы. Кроме того, поскольку он использует случайное количество минут (не секунд), время начала не такое уж случайное, как могло бы быть. Но $ RANDOM увеличивается только до 32 767, а между 9 утра и 11 вечера есть 50 400 секунд, было бы немного сложнее рандомизировать секунды. Наконец, поскольку время запуска случайное и не зависит друг от друга, возможно (но маловероятно), что два или более экземпляра скрипта будут запущены одновременно.
Вы можете сделать арифметические присвоения более удобочитаемыми, убрав знак доллара и сдвинув двойные скобки влево (например, ((maxdelay = 14 * 60))или ((delay = $RANDOM % maxdelay))). sleepАргумент еще должен быть путь у вас есть (хотя вы можете добавить пробелы, если это необходимо).
Приостановлено до дальнейшего уведомления.
1
Это сработало и для меня. Мой пользовательский сценарий bash выглядит так, как sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
показано
Мне что-то не хватает, или максимальная задержка должна быть установлена на maxdelay = $ ((14 *
60/20
@jenishSakhiya Случайные задержки для каждого из 20 прогонов абсолютны (ну, начиная с 9 утра), а не относительно другого из прогонов. То есть, если одна из случайных задержек составляет 13 часов, это означает, что она будет работать в 22:00 (13 часов после 9:00), а не через 13 часов после любого из других запусков.
Гордон Дэвиссон
139
Да, да, этому вопросу больше года, но, может быть, я могу добавить что-нибудь полезное:
Как выполнить cron с произвольным смещением 20 раз в день с 9 утра до 11 вечера? В cron это довольно сложно, потому что вы делите 14 часов на 20 времени выполнения. Мне не очень нравятся другие ответы, потому что они требуют написания сценария-оболочки bash для вашего php-сценария.
Однако, если вы позволите мне облегчить ограничение времени и частоты до 13 раз с 8:30 до 23:09, это может помочь, и все это в пределах вашего crontab:
$ {RANDOM: 3: 2} использует $ RANDOM из bash, о котором упоминалось выше, но добавляет нарезку массива bash. Поскольку переменные bash не типизированы, псевдослучайное подписанное 16-битное число усекается до первых 2 из 5 десятичных цифр, что дает вам краткую однострочную запись для задержки вашего cronjob между 10 и 99 минутами (хотя распределение смещено в сторону С 10 по 32).
Следующее также может сработать для вас, но я обнаружил, что он по какой-то причине «менее случайен» (возможно, закон Бенфорда запускается путем модуляции псевдослучайных чисел. Эй, я не знаю, я завалил математику ... на баш!):
Вы должны отобразить модуль как '\%' выше, потому что cron (ну, по крайней мере, Linux 'vixie-cron') завершает строку, когда встречает неэкранированный '%'.
Возможно, вы могли бы получить оставшиеся 7 исполнений скрипта, добавив еще одну строку с другим 7-часовым диапазоном. Или ослабьте свое ограничение, чтобы бегать с 3 утра до 11 вечера.
Мне нравится поздний ответ. Но если вы пытаетесь сгенерировать случайное целое число, равномерно распределенное в диапазоне от 10 до 99, а результат RANDOM составляет от 0 до 32 767, почему бы вам просто не сделать $[(RANDOM/368)+10]?
jsdalton
3
@jsdalton: Разве оператор по модулю не был бы лучше? $((RANDOM % 90 + 10))Тест:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
geon
5
Во многих системах хрон не использует Баш по умолчанию , так что может быть лучше , чтобы избежать bashism $RANDOM: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m.
pabouk
9
Убедитесь , что crontabиспользуется , bashпрежде чем использовать $RANDOM. Если у вас есть vixie-cron(похоже, мой случай на Ubuntu), то вы можете добавить SHELL=/bin/bashв начало. Здесь есть другие альтернативы для других версий cron: superuser.com/a/264541/260350
DaAwesomeP
1
Когда я использую первое предложение выше, я получаю, crontab: errors in crontab file, can't install. Do you want to retry the same edit?пожалуйста, помощь
Сеано
72
Итак, я использую следующее для запуска команды между 01:00 и 330:00.
:: MindBLOWN :: еще одно непонятное место, где можно использовать немного Perl.
Марк Карпентер-младший,
Это определенно самый чистый ответ
Энрико Детома
Это неэффективно, поскольку вы создаете много процессов.
kahveciderin
21
Cron предлагает RANDOM_DELAYпеременную. Подробнее crontab(5)см.
Переменная RANDOM_DELAY позволяет задерживать запуск задания на произвольное количество минут с верхним пределом, указанным переменной.
Это часто встречается на anacronрабочих местах, но также может быть полезно в crontab.
Вам может потребоваться быть осторожным с этим, если у вас есть некоторые задания, которые выполняются с мелкой (минутной) детализацией, а другие - с грубой.
Я хотел бы использовать переменную RANDOM_DELAY, но не могу найти никаких подсказок на странице руководства crontab (5) в Ubuntu 14.04.4 LTS.
Exocom
Это неудачно. Интересно, а там не поддерживается. Я вижу это задокументировано на этой странице руководства по Centos 7 и Arch Linux.
Мика Эллиотт,
9
это кажется правильным ответом, но вы можете привести пример?
chovy
14
Обратите внимание, что RANDOM_DELAYон устанавливается один раз и остается постоянным в течение всего времени работы демона.
Maciej Swic
5
RANDOM_DELAYФлаг особенность cronie-crond в то время как Ubuntu , кажется, работает в vixie-cronкотором отсутствует этот флаг.
kravietz
7
Моя первая мысль заключалась в том, чтобы создать одно задание cron, запускающее 20 заданий, случайно запланированных для этого. atПолезности (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) используются для выполнения команд в заданное время.
Если кому-то интересно, например, мне:% N предоставляет текущие наноразмеры, но на некоторых страницах руководства отсутствует информация по нему. Это очень умное решение для людей, которым просто нужна «некоторая случайность» для каждой команды.
Thorsten Schöning
Помимо предостережений, уже описанных в другом месте, это будет работать, только если у вас есть GNU date(что вы, вероятно, делаете на большинстве Linux, но не на Busybox, стандартной MacOS или различных других платформах, основанных на BSD).
тройняшек
4
Решение al-x не работает для меня, поскольку команды crontab выполняются не в bash, а в sh, я думаю. Что работает:
Я перепробовал все, но у меня все равно не получилось. Ваш пост объяснил, почему, спасибо!
marlar
$[ ... ]является устаревшим синтаксисом с тех пор, как он вернулся; для чего-либо из этого тысячелетия вы бы предпочли $((RANDOM\%90))mPOSIX-совместимый синтаксис (но, конечно, RANDOMпо-прежнему только Bash).
тройняшек
1
at -f [file] [timespec]
или
echo [command] | at [timespec]
или
at [timespec]... и интерактивная спецификация, такая как scriptзапись.
Команда
При запуске текст предоставляется на стандартный ввод или в файл, указанный в -f [file].
24-часовое время , как 4-значного междунар, например 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, но он не ожидает, что ваш компьютер будет работать круглосуточно (как наши ноутбуки), и будет запускать сценарии, которые он пропустил из-за того, что система вышла из строя.
Не обходите систему репутации, размещая комментарии в качестве ответов. Однако ваш комментарий выглядит достаточно хорошо, чтобы на самом деле быть ответом. Я рекомендую удалить « У меня нет представителя, чтобы добавить комментарий, но ».
Тед Люнгмо,
1
Я только что просмотрел этот ответ и пропустил ту часть, где вы задаете вопрос взамен в конце (небрежная работа с моей стороны). Не задавайте вопросов в ответах. Разместите свой вопрос, если у вас есть вопросы. Я превратил ваш полу-вопрос в нечто, что могло бы сойти за ответ.
Тед Люнгмо,
1
Понял! Спасибо. В следующий раз я буду поосторожнее, никаких злых умыслов не было.
mellofellow
1
Я уверен, что у вас не было злых умыслов, и вам не нужно быть слишком осторожным. Вы наметили возможное решение - и в конце немного споткнулись. Не беспокойся!
Тед Люнгмо,
0
Я понимаю, что это старый поток, но я хочу добавить одну вещь, связанную со случайными значениями, которую я часто использую. Вместо использования переменной $ RANDOM с фиксированным и ограниченным диапазоном я часто делаю случайные значения произвольного диапазона в оболочке с помощью
dd if=/dev/urandom bs=4 count=12>/dev/null | od -N4 -t u4 -A none
так что вы можете сделать, например,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=12>/dev/null | od -N4 -t u4 -A none)
и преодолеть некоторые ограничения, которые обсуждались в этой ветке.
Добро пожаловать в SO. Что ж, старая ветка или нет, это отправило меня, ~$info ddи я могу понять, что происходит с левой стороны |, но не могу разобрать правую сторону. Итак, для меня и других, интересующихся overcoming some restrictionsгенерацией случайных значений, почему бы не уделить время объяснению RHS и сделать более убедительный аргумент в пользу использования вашего подхода. Глубина объяснения позволяет людям чувствовать себя комфортно как с процессом, который вы предлагаете, так и с его преимуществами. Спасибо.
Крис
Ах хорошо. od aka «восьмеричный дамп» принимает файл или стандартный ввод и выгружает двоичные данные в удобочитаемой форме. Мы хотим, чтобы наш номер отображался в виде десятичной дроби без знака (-t u4), и нам не нужен индекс адреса (-A none). -N4 является избыточным, поскольку мы берем только 4 байта, но это тоже не повредит. Надеюсь, это объясняет ...
Ответы:
Если я понимаю, что вы ищете, вам нужно сделать что-то немного беспорядочное, например, создать задание cron, которое запускает сценарий bash, который рандомизирует время выполнения ... Примерно так:
crontab:
и в / путь / к / bashscript:
Несколько примечаний: этот подход немного расточителен, поскольку он запускает 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:
$ {RANDOM: 3: 2} использует $ RANDOM из bash, о котором упоминалось выше, но добавляет нарезку массива bash. Поскольку переменные bash не типизированы, псевдослучайное подписанное 16-битное число усекается до первых 2 из 5 десятичных цифр, что дает вам краткую однострочную запись для задержки вашего cronjob между 10 и 99 минутами (хотя распределение смещено в сторону С 10 по 32).
Следующее также может сработать для вас, но я обнаружил, что он по какой-то причине «менее случайен» (возможно, закон Бенфорда запускается путем модуляции псевдослучайных чисел. Эй, я не знаю, я завалил математику ... на баш!):
Вы должны отобразить модуль как '\%' выше, потому что 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/260350crontab: errors in crontab file, can't install. Do you want to retry the same edit?
пожалуйста, помощьИтак, я использую следующее для запуска команды между 01:00 и 330:00.
Это позаботилось о моих случайных потребностях. Это 9000 секунд == 150 минут == 2,5 часа
источник
Cron предлагает
RANDOM_DELAY
переменную. Подробнееcrontab(5)
см.Это часто встречается на
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
источник
date
(что вы, вероятно, делаете на большинстве Linux, но не на Busybox, стандартной MacOS или различных других платформах, основанных на BSD).Решение al-x не работает для меня, поскольку команды crontab выполняются не в bash, а в sh, я думаю. Что работает:
источник
$[ ... ]
является устаревшим синтаксисом с тех пор, как он вернулся; для чего-либо из этого тысячелетия вы бы предпочли$((RANDOM\%90))m
POSIX-совместимый синтаксис (но, конечно,RANDOM
по-прежнему только Bash).at -f [file] [timespec]
или
echo [command] | at [timespec]
или
at [timespec]
... и интерактивная спецификация, такая какscript
запись.Команда
При запуске текст предоставляется на стандартный ввод или в файл, указанный в
-f [file]
.Timespec
Вот
[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), вы можете редактировать
и добавить
Где XX - это количество минут, на которое вы хотите отложить базовое задание.
Anacron похож на cron, но он не ожидает, что ваш компьютер будет работать круглосуточно (как наши ноутбуки), и будет запускать сценарии, которые он пропустил из-за того, что система вышла из строя.
источник
В этом примере вы можете попробовать использовать случайное время перед выполнением команды:
источник
А как насчет создания сценария, который каждый день перезаписывает crontab?
источник
Я понимаю, что это старый поток, но я хочу добавить одну вещь, связанную со случайными значениями, которую я часто использую. Вместо использования переменной $ RANDOM с фиксированным и ограниченным диапазоном я часто делаю случайные значения произвольного диапазона в оболочке с помощью
так что вы можете сделать, например,
и преодолеть некоторые ограничения, которые обсуждались в этой ветке.
источник
~$info dd
и я могу понять, что происходит с левой стороны|
, но не могу разобрать правую сторону. Итак, для меня и других, интересующихсяovercoming some restrictions
генерацией случайных значений, почему бы не уделить время объяснению RHS и сделать более убедительный аргумент в пользу использования вашего подхода. Глубина объяснения позволяет людям чувствовать себя комфортно как с процессом, который вы предлагаете, так и с его преимуществами. Спасибо.