The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Случайная задержка в shell-скрипте, выполняемом из crontab (без башизмов)
применимо в системах без anacron, без /etc/cron.[hourly|daily|weekly|monthly] и без systemd.

цель: чтобы вписать простую строку в crontab вида

   0 */8  * * * $HOME/bin/script.sh

но при этом иметь случайное начало работы (а не ровно 00:00, 08:00 и 16:00), 
в начале script.sh нужно поместить

   R0=`dd if=/dev/urandom bs=1 count=4 status=none | od -t u4 | head -1 | cut -c 8-`
   sleep `echo "scale=0;" $R0 % 3601 | bc`

задержка будет случайная, равномерно распределённая в интервале от 0 до 3600 секунд.
 
24.07.2022 , Автор: john_erohin
Ключи: shell, cron, random, sleep / Лицензия: CC-BY
Раздел:    Корень / Программисту и web-разработчику / Shell / Готовые скрипты

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, Аноним (1), 14:45, 27/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Чего только люди не придумают, чтобы jot не ставить
     
     
  • 2.7, Аноним (7), 10:54, 28/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Люди про неё не знают.
     
     
  • 3.46, A (?), 19:23, 17/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Ведь из примитивов можно всё соорудить быстро. Остальное интересно, полезно, нужно, но необходимости нет. Т.к. из примитивов соорудить можно.
     
  • 2.12, Аноним (12), 23:46, 28/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    >  Чего только люди не придумают, чтобы systemd не ставить

    // fix

     

  • 1.2, grayich (ok), 14:52, 27/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +8 +/


    sleep $((RANDOM % 3600))
    sleep $(shuf -i 1-3600 -n 1)
    sleep $(perl -e 'print rand(3600)')
    sleep $(python -c 'import random; print(random.randint(1,3600))')


    и ещё десяток более коротких вариантов, в зависимости от системы и имеющихся утилит
    трудно найти систему в которой есть od, bc и при этом нет продвинутого шела, shuf, perl, python и порочего
     
     
  • 2.3, Аноним (3), 21:02, 27/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Это баш, кореутилс, перл, питон. В какой-нибудь фряхе tcsh вот и попробуй с ним сделать что-нибудь.
     
     
  • 3.4, grayich (ok), 22:41, 27/07/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    в фряхе в базовой системе(из коробки) есть jot, как выше предлагали

    jot -r 1 1 3600


    сабж интересен с точки зрения задачки для ума, но в реальности .. такое себе
    coreutils везде есть, awk везде есть

    awk 'BEGIN{srand();print rand()*3600}'

    если в системе есть [b]od bc dd head cut[/b] то и предлагаемое скорее всего есть
     
  • 2.5, john_erohin (?), 04:37, 28/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > продвинутого шела,

    я когда подавал эту заметку на модерирование, в заголовке специально
    написал "без башизмов". но дорогая редакция не пропустила.
    оскорбить боятся кого-то что ли.

    перл и питон слишком жирные. можно обойтись без.

     
     
  • 3.6, grayich (ok), 10:22, 28/07/2022 [^] [^^] [^^^] [ответить]  
  • +2 +/
    > написал "без башизмов". но дорогая редакция не пропустила.

    идея была ясна, но имхо - чисто из теории
    на практике нет смысла таких сложностей, да и те-же jot, shuf - не башизмы

    > перл и питон слишком жирные. можно обойтись без.

    да как сказать, задействованные утилиты:
    91K /usr/bin/bc
    39K /usr/bin/cut
    67K /usr/bin/dd
    39K /usr/bin/head
    63K /usr/bin/od
    итого: 299КБ

    14К /usr/bin/jot
    43K /usr/bin/shuf

    687K /usr/bin/gawk

    perl\python - обычно уже в системе есть, общий их размер конечно приличный, но выполняемый(вид из ps)
    13364  7784 python -c import random; print(random.randint(1,3600)); input("")
    10636  3796 perl -e print rand(3600);$i=<STDIN>

    и тут вроде бы как 10-13 метров много, но те-же bc\head занимают по 6 метров в ps, что уже в сумме 12
    так что по ресурсам perl\python в итоге ещё и экономнее будут - чем целый конвейер

     
     
  • 4.14, Аноним (-), 23:52, 28/07/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Повесить в памяти жирный интерпретер, да еще с немеряными модулями/стдлибами чтобы задержку отмерять это конечно круто. Надо было не мелочиться и V8 для этого заюзать, чего уж там. Или JVM накрайняк. Иначе недостаточно энтерпрайзно.

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

     
     
  • 5.15, john_erohin (?), 06:33, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > Можно еще Менеджер Рандомных Задержек накодить

    systemd-randomdelayd.

     
     
  • 6.16, Аноним (-), 13:13, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    А может, просто man systemd.timer? Он умеет и это и намного больше :). Заодно крон можно отправить на свалку - в системде хотя-бы можно посмотреть активные таймеры ОДНОЙ командой. Сразу. Без велосипедизма. С кроном так почему-то не катит.

    Зато можно написать очередной совет как делать из буханки хлеба троллейбус, "без использования гвоздей".

     
     
  • 7.27, john_erohin (?), 21:34, 30/07/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > в системде хотя-бы можно посмотреть активные таймеры ОДНОЙ командой.

    таймер в системе один, это системные часы, их cron и смотрит.

    все начинается с нестандартной терминологии, а заканчивается переходом отработавшего задание агента влияния к своему настоящему хозяину.

     
     
  • 8.28, Аноним (28), 17:25, 31/07/2022 [^] [^^] [^^^] [ответить]  
  • –1 +/
    В системде есть юниты с типом timer и их в типовом случае таки более одного Эт... текст свёрнут, показать
     

  • 1.8, OpenEcho (?), 11:58, 28/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +4 +/
    Plain C:
    '''
    #include <time.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>

    void main () {
      srand(time(NULL));
      int r = rand() % 3600;
      printf("\nSleeping for %d seconds\n", r);
      sleep(r);
    }
    '''

    Go: (go build -ldflags "-s -w" this_source.go) << будет работать везде т.к. статика
    '''
    package main

    import "fmt"
    import "math/rand"
    import "time"

    func main() {
        rnd := time.Now().UTC().UnixNano()
        rand.Seed(rnd)
        rs  := rand.Intn(3600)
        fmt.Println("Sleeping for: ",rs," second(s)")
        time.Sleep(time.Duration(rs) * time.Second)
    }
    '''


     
     
  • 2.18, Аноним (18), 16:14, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > srand(time(NULL))

    Это точно нормальный вариант? У десятка задач будет одинаковое время запуска (с точностью до секунды)... и одинаковый random seed...
    Тогда уж лучше getpid().

     
     
  • 3.20, OpenEcho (?), 18:10, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    >> srand(time(NULL))
    > Это точно нормальный вариант?

    Точно:

    > srand(time(NULL));

    makes use of the computer's internal clock to control the choice of the seed.  Since time is continually changing, the seed is forever changing.  Remember, if the seed number remains the same, the sequence of numbers will be repeated for each run of the program.

     
     
  • 4.24, Аноним (24), 00:28, 30/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Ну вот запустил крон 10 штук процессов в одну и ту же секунду. Все 10 процессов выполнили time и получили одинаковое значение. И у всех процессов будет одинаковый начальный random seed (например, у меня сейчас 1659129796). И все 10 потом стартанут через одинаковую паузу...

    Точно надо было этого добиться?

     
     
  • 5.25, OpenEcho (?), 13:48, 30/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > Ну вот запустил крон 10 штук процессов в одну и ту же
    > секунду.

    Можно ткуть в ту самую строчку, где в тех.задании сказанно про число 10?
    ОП, хочет запускать ОДИН шел скрипт. Не надо придумывать то, что не спрашивали и не надо быть телепатом, чтоб угадать наперед все что можно случиться, - это первое правило в любом серьезном бизнесе - "делай то, что сказанно". Нужна функция случайной задержки в пределах заданного времени, В СКРИПТЕ шела, чтобы запустить что-то позже, опять же, что то "ОДНО". Все. Одноразово.

    О каких 10 процессах речь? Зачем усложнять там, где это - НЕ НУЖНО


     
  • 5.26, Аноним (26), 16:54, 30/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Про 10 параллельно запускаемых задач нет ни слова. Это была моя попытка проиллюстрировать почему решение получилось не очень на конкретном примере. Неудачная попытка.

    В решении (и в задании) ОПа написано
    > Случайная задержка в shell-скрипте
    > задержка будет случайная

    У тебя получилась скорее РАЗНАЯ (и при этом ПРОГНОЗИРУЕМАЯ, тов. майор) задержка, но не СЛУЧАЙНАЯ! Можно достаточно точно предсказать в какое время каждый день скрипт будет отрабатывать. Так себе случайность, на месте ОПа я бы твоё решение не принял и отправил на доработку как несоответствующее заданию.
    А вот на месте тов. майора федеральной службы - всячески бы топил за твой вариант.

     

  • 1.9, OpenEcho (?), 12:05, 28/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +2 +/
    #!/bin/sh
    sleep $(echo "select abs(random()%3600);" | sqlite3)
     
  • 1.10, Аноним (-), 17:46, 28/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • –1 +/
    гыг, это типа как суть плоского анекдота объяснять кому-то
     
  • 1.11, Аноним (11), 23:24, 28/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    bc значит у него есть, а shuf нет... Вероятно, недоучили баш, недоучили шелл, недоучили всё. Но это не мешает радоваться изобретенному велосипеду и учить других.

    Сама постановка задачи странная, если не сказать больше. Планировщик задач в принципе про точное время запуска. Задержку логично встроить в запускаемую программу. Кстати, зачем она? Если это с целью размазать нагрузку от массово стартующих скриптов, то логичнее обрабатывать их очередью, в лимитированное количество потоков. Это все тоже делается без всяких башизмов.
    По крону стартуете runner.sh, внутри которого что-то вроде ls dir/with/scripts/*sh | xargs -L1 -P4 sh
    Скриптам можно дать имена типа 00-first-prio.sh 00-first-prio2.sh 10-second-prio.sh и так далее.

     
     
  • 2.17, OpenEcho (?), 16:01, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Многие дистрибутивы делают рэндомный запуск скриптов апдейта, чтобы уменшить ударную нагрузку от массы клиентов
     
     
  • 3.19, Аноним (11), 17:00, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Значит им тоже надо головой подумать и понять, что рандомные задержки проблему не решают.
    Что если апдейт одного из пакетов может в одиночку нагрузить систему? Так не бывает - скажут они, и добавят, что если даже это так, то пусть себе всё тормозит.
    Когда-то кто-то скостылил, а теперь так делают все и вроде как это стало правильным способом? Ну-ну.

    Или как я уже написал - лимитировать запуск процессов, запуская их по очереди, или запускать их в cgroup, в которой они будут получать ресурсы по квоте (этот вариант наверно самый лучший). nice точно везде есть.

     
     
  • 4.21, OpenEcho (?), 18:16, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • –1 +/
    > Значит им тоже надо головой подумать и понять, что рандомные задержки проблему
    > не решают.

    Неправда, разгружает и очень прилично

    > Что если апдейт одного из пакетов может в одиночку нагрузить систему?

    Разгружает загрузку на сервера которые предоставляют апдейты, причем здесь клиенты и как долго они будут процессировать полученный апдэйт? Смысл в том чтоб предотвратирь ДДоС серваков, если все однаразово ломануться качать

     
     
  • 5.22, Аноним (22), 19:59, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • +/
    А, вы про это. Что будет, если клиенты отключат задержку, чтобы получить обновления раньше?
    Понятно что - перегруженная инфраструктура будет.
     
     
  • 6.23, OpenEcho (?), 21:11, 29/07/2022 [^] [^^] [^^^] [ответить]  
  • –1 +/
    > А, вы про это. Что будет, если клиенты отключат задержку, чтобы получить
    > обновления раньше?

    Все сразу и все выставят одно и то же время? По моему это очень маленькая вероятность...

    Можно конечно сделать как мелкософт и рулить централизованно, но тогда - "Прощай свобода..."

     
  • 4.33, Kuromi (ok), 15:30, 05/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Вспомните что происходит когда условная Убунта релизит новый выпуск - серверы пусть и не лежат, но ощутимо перегружены. Умные чукчи сами ждут недельку, если не ностальгируют по дайлапу
     
  • 2.32, gapsf2 (ok), 15:15, 04/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > ls dir/with/scripts/*sh | xargs -L1 -P4 sh

    https://mywiki.wooledge.org/BashPitfalls#Using_xargs_without_-0
    http://mywiki.wooledge.org/ParsingLs
    https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29
    https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-d

     
     
  • 3.34, Аноним (11), 23:35, 05/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Любители засирать шелл-скрипты бессмысленными флажками такие любители. Лишь бы пять копеек вставить. Скрипты в папку кладет администратор, он же дает имена файлам. Администратор-дебил создаст файл с именем, часть которого превратится в команду? Кстати, сможешь составить такое имя файла? Или как всегда, лишь бы квакнуть?
     

  • 1.13, Аноним (11), 23:47, 28/07/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +2 +/
    'echo 3600 '*' $(od -An -N2 -i /dev/urandom) / 65536 | bc'

    Решение на od | bc, так сказать, облегченное (:

    Еще раз - кто не умеет, тот учит.

     
  • 1.29, ABATAPA (ok), 20:47, 03/08/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    root@OpenWrt:~# od
    -ash: od: not found
    root@OpenWrt:~# bc
    -ash: bc: not found
    root@OpenWrt:~# sh --version


    BusyBox v1.33.2 (2022-02-16 20:29:10 UTC) built-in shell (ash)

    root@OpenWrt:~# SEED=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | md5sum | sed 's/[a-f]//g' | cut -c1-10)
    root@OpenWrt:~# expr $SEED % 90
    38
    root@OpenWrt:~# SEED=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | md5sum | sed 's/[a-f]//g' | cut -c1-10)
    root@OpenWrt:~# expr $SEED % 90
    75

     
     
  • 2.38, john_erohin (?), 11:29, 08/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    > md5sum | sed 's/[a-f]//g'

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

     

  • 1.30, aa (?), 06:47, 04/08/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +3 +/
    man 5 crontab

    ...
    The RANDOM_DELAY variable allows delaying job startups by random
    amount of minutes with upper limit specified by the variable.
    - всё уже придумано

     
     
  • 2.31, Аноним (31), 10:41, 04/08/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    не мешай человек НЕ читать маны и изобретать велосипеды
     
  • 2.36, john_erohin (?), 11:20, 08/08/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    devuan:
    $ man 5 crontab | grep -i RANDOM_DELAY | wc -l
    0

    cygwin: то же самое.

    вангую: у вас не викси крон, а его имитация от линуса поттера.

     

  • 1.35, бублички (?), 20:35, 07/08/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    > dd if=/dev/urandom bs=1 count=4 status=none | od -t u4 | head -1 | cut -c 8-

    до чего уродливая конструкция. впрочем чего можно ожидать от очередного Дениса Попова, что даже погуглить не умеет чтоб отыскать к примеру: od -vAn -N2 -tu4 < /dev/urandom

     
     
  • 2.37, john_erohin (?), 11:24, 08/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    ваша конструкция почему-то не способна выдать больше чем 65535.

     
     
  • 3.39, vodz (ok), 13:03, 08/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Ну надо -N4, да и для scale=0 bc не надо:
    R='od -vAn -N4 -tu4 < /dev/urandom'
    sleep 'expr $R % 3601'
     
  • 3.40, Аноним (11), 13:15, 08/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    Для практических нужд это запредельно много.
     
  • 3.41, бублички (?), 15:17, 09/08/2022 [^] [^^] [^^^] [ответить]  
  • +1 +/
    в задании итого меньше требовалось (от 0 до 3600)
     
     
  • 4.42, john_erohin (?), 15:43, 09/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    >  в задании итого меньше требовалось

    свою нетленку вы пишете так же ? шаг вправо-влево считается побег, попытка подумать - провокация.

    потребоваться может от 3 до 9000000

     
     
  • 5.44, бублички (?), 17:00, 09/08/2022 [^] [^^] [^^^] [ответить]  
  • +/
    >>  в задании итого меньше требовалось
    > свою нетленку вы пишете так же ? шаг вправо-влево считается побег, попытка
    > подумать - провокация.
    > потребоваться может от 3 до 9000000

    довольно странный вы гражданин. сначала публикуете нечто пионерско-босоногое (типа cat <file1>|grep <string>|head -1|cut -c8|sort|uniq|echo > <file2>), потом обижаетесь на критику и начинаете придираться выдумывая то чего изначально не было. снова и вновь - инфантильно и невежественно

     

  • 1.45, snarkx (?), 07:53, 12/08/2022 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    А ведь где-то для этого используют jvm, и обязательно, обязательно Spring Boot.

    Или не энтерпрайзно

     


     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Спонсоры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2022 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру