Назад | Перейти на главную страницу

Как мне поспать миллисекунду в bash или ksh

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

# wait one second please 
sleep 1

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

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

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

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

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 суффикс. Если ваш дистрибутив / ОС не сделал что-то творческое (к сожалению, сборка RHEL / CentOS 8 bash-4.4 с загружаемыми расширениями сознательно удалено), вместо этого вы сможете:

[ -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

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

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 нет оболочки usleep), поэтому я написал свою собственную так:

  #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/.