Как мне спать в течение миллисекунды в Bash или Ksh

sleep - очень популярная команда, и мы можем начать спать с 1 секунды:

# wait one second please 
sleep 1

но какая альтернатива, если мне нужно подождать всего 0,1 секунды или от 0,1 до 1 секунды?

  • примечание: на Linux или OS X sleep 0.XXX работает отлично, но на солярисе sleep 0.1 или же sleep 0.01 - неправильный синтаксис

8 ответов

Решение

Bash имеет "загружаемый" спящий режим, который поддерживает доли секунды и устраняет накладные расходы внешней команды:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

Затем:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

Недостатком является то, что загружаемые материалы не могут быть предоставлены с bash двоичный файл, поэтому вам нужно будет скомпилировать их самостоятельно, как показано (хотя в Solaris это не обязательно будет так просто, как описано выше).

По состоянию на bash-4.4 (Сентябрь 2016 г.) все загружаемые файлы теперь создаются и устанавливаются по умолчанию на платформах, которые его поддерживают, хотя они создаются как отдельные файлы общего объекта и без .so суффикс. Если ваш дистрибутив / ОС не сделал что-то творческое, вы должны иметь возможность сделать следующее:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(Страница руководства подразумевает BASH_LOADABLES_PATH устанавливается автоматически, я считаю, что это не так в официальном выпуске по состоянию на 4.4.12. Если и когда он установлен правильно, вам нужно только enable -f filename commandname как требуется.)

Если это не подходит, следующая самая простая вещь, которую нужно сделать, это построить или получить sleep из GNU coreutils это поддерживает необходимую функцию. POSIX sleep Команда минимальна, в старых версиях Solaris реализовано только это. Солярис 11 sleep поддерживает доли секунды.

В крайнем случае вы могли бы использовать perl (или любой другой сценарий, который вам нужно передать) с оговоркой, что инициализация переводчика может быть сопоставима с предполагаемым временем сна:

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh

Документация для sleep Команда из coreutils говорит:

Исторические реализации sleep требовали, чтобы число было целым числом, и принимали только один аргумент без суффикса. Тем не менее, GNU Sleep принимает произвольные числа с плавающей запятой. Смотрите с плавающей точкой.

Следовательно, вы можете использовать sleep 0.1, sleep 1.0e-1 и подобные аргументы.

Сон принимает десятичные числа, чтобы вы могли разбить его следующим образом:

1/2 секунды

 sleep 0.5

1/100 секунды

sleep 0.01

Так что за миллисекунду вы хотели бы

sleep 0.001

Попробуйте это, чтобы определить точность:

    time sleep 0.5      # 500 milliseconds (1/2 of a second)
    time sleep 0.001    # 1 millisecond (1/1000 of a second)
    time sleep 1.0      # 1 second (1000 milliseconds)

Сочетание раствора г-на Спуратика и раствора Коулса.

Вы можете просто использовать usleep, Это занимает микросекунды (= 1e-6 секунд) в качестве параметра, поэтому для сна 1 миллисекунды вы должны ввести:

usleep 1000

У меня была та же проблема (без оболочки, использующей Solaris), поэтому я написал свою собственную так:

  #include "stdio.h"
  int main(int argc, char **argv) {
     if(argc == 2) { usleep(atoi(argv[1])); }
     return 0;
}

Не проверяет аргументы - я бы порекомендовал правильно написанный, если вы хотите сохранить его, но это (gcc usleep.c -o usleep) выведет вас из дыры.

Мне нравится идея уснуть, но я не могу комментировать под ней. Так как это помогло мне, я надеюсь, что мое предложение может улучшить идею уснуть.

https://github.com/fedora-sysv/initscripts/blob/3c3fe4a4d1b2a1113ed302df3ac9866ded51b01b/src/usleep.c является актуальным исходным кодом для usleep.c в экосистеме redhat.

Попробуйте скомпилировать это в своем Solaris. Вам, вероятно, понадобится https://www.opencsw.org/packages/libpopt0/.

Спецификация POSIX дляпринимает только целочисленный аргумент, то есть никаких долей секунды. GNUосновные утилитыsleepдобавляет поддержку действительных чисел, суффиксов, даже научных обозначений иinfinity как расширения GNU . Но если вы используете встроенную систему сbusyboxили у вас просто нет coreutils, тогда вам не повезло, если у вас нет Perl.

      perl -e 'select(undef, undef, undef, 0.1);'
Другие вопросы по тегам