Как выспать случайную долю секунды в оболочке POSIX? - PullRequest
1 голос
/ 13 октября 2011

Следующее не будет работать:

/bin/sleep $(printf ".%02ds" $(( $RANDOM % 100 )))
  1. POSIX sleep поддерживает только целые секунды
  2. нет $RANDOM

Я мог бы подражать случайным образом:

RAND255=$(od -An -N1 -t u1 /dev/urandom)

Другой вариант - написать небольшую программу на C, которая использует usleep() и *rand*()как предложено @ dmckee и @ Кит Томпсон .Развертывание такой программы может быть не всегда возможным.

Есть ли лучший способ , т. Е. Есть ли альтернатива для сна в POSIX, которая принимает доли секунды, отличные от рукописной программы Cи есть ли лучший способ эмулировать $RANDOM, кроме od?

Ответы [ 4 ]

3 голосов
/ 13 октября 2011

В вашей первой команде, например, если $RANDOM % 100 равно 6, она вызовет /bin/sleep .6s; Вы хотите /bin/sleep .06s.

Во второй команде od -An -N1 -t u1 /dev/random, кажется, печатает число в диапазоне 0..255 - и сама команда может задержаться на длительное время, если /dev/random исчерпает энтропию. Вместо этого используйте /dev/urandom.

Я бы написал небольшую программу на C, которая вызывает usleep() (при условии, что компиляция и развертывание исполняемого файла возможны).

EDIT

Насколько я могу судить, ответ на ваш (обновленный) вопрос - нет.

POSIX не гарантирует / dev / urandom, поэтому ваша команда od не переносима на все системы POSIX. Я не верю, что POSIX определяет любую команду, которая может спать в течение нескольких секунд. Он определяет функцию nanosleep(), но если вы не можете обязательно развернуть программу на Си, которая не помогает. POSIX awk не имеет функции сна. Perl не POSIX.

Ваши варианты: (1) спать только целые секунды или (2) использовать непереносимый метод.

В каких условиях вам это нужно?

2 голосов
/ 14 октября 2011

Генератор случайных чисел Клиффа - это очень простой генератор случайных чисел, который «проходит проверку на шумовую сферу на случайность, не показывая структуры». Он легко программируется менее чем за 10 строк кода awk:

 # cliff_rand.awk --- generate Cliff random numbers



 BEGIN { _cliff_seed = 0.1 }

 function cliff_rand()
 {
     _cliff_seed = (100 * log(_cliff_seed)) % 1
     if (_cliff_seed < 0)
         _cliff_seed = - _cliff_seed
     return _cliff_seed
 }

Этот алгоритм требует начального «начального числа» 0,1. Каждое новое значение использует текущее начальное значение в качестве входных данных для расчета. Если встроенная функция rand () (см. Числовые функции) не является достаточно случайной, вы можете попробовать использовать эту функцию.

Взят от здесь

2 голосов
/ 13 октября 2011

Perl имеет usleep, но в загруженной системе время загрузки, вероятно, преобладает над коротким сном.

0 голосов
/ 02 февраля 2019

это решение работает на linux путем опроса монотонного счетчика / proc / uptime - оно работает даже на медленных системах с точностью до 1/100 секунды:

#!/bin/sh

WAIT=567        # 5.67 sec

get_up()
{
        read -r UP REST </proc/uptime
        export UP=${UP%.*}${UP#*.}
}

get_up; START=$UP
while :; do get_up; test $((UP-START)) -ge $WAIT && break; done

Быстрый и грязный oneliner (копировать / вставить!) Здесь:

W=567;x(){ read U R </proc/uptime;U=${U%.*}${U#*.};};x;S=$U;while :;do x;test $((U-S)) -ge $W && break;done
...