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


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

# wait one second please 
sleep 1

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

  • примечание: на linux sleep 0.XXX отлично работает, но на солнечной sleep 0.1 или sleep 0.01 - незаконный синтаксис

99
2018-01-15 13:19


Источник


Могу ли я спросить, почему вы хотите спать за 1 миллион? - Tom O'Connor
Да, конечно, в моем сценарии bash я добавляю «sleep 1», в некоторых строках, но скрипт выполняется очень медленно, поэтому после некоторого завершения я вычисляю, что сон 0,1 также приносит хорошие результаты и быстрее. О задержке мне нужна задержка в порядке для решения проблемы ssh в моем скрипте bash, я выполняю пароли ssh на некоторых машинах, ожидая и без задержки, что это не сработает. Как вы знаете из моего вопроса, задержка должна соответствовать как Linux, так и Solaris - yael
Независимо от того, какое решение вы выберете, имейте в виду, что сценарий оболочки не будет очень точным с точки зрения времени. - scai
Как насчет выполнения чего-то, что требуется очень короткое время для выполнения, но ничего не делает .. как echo "" >/dev/null - Tom O'Connor
Хорошая идея, но как эта команда выполняет эту команду? , Мне нужно 0,1 мс, не менее того - :) - yael


Ответы:


У 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 реализованы только для этого. Solaris 11 sleep  делает поддержка дробных секунд.

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

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

57
2018-01-15 13:52



Ах, поскольку вы используете expect вы можете просто использовать "after N", где N - миллисекунды, прямо в вашем скрипте. - mr.spuratic
использование usleep как @Luis Vazquez и @sebix пишут - Ilan.K


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

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

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


97
2018-01-15 13:22



см. мое замечание о ОС SOLARIS - yael
Вы перепутали является а также не? - scai
см. мое обновление в моем quastion - yael
Яэль, я думаю, что в вашем вопросе еще слишком много негативов; вы уверены, что имеете в виду «не незаконный синтаксис»? - MadHatter
например, я бегу на solaris 10: # sleep 0.1 sleep: плохой символ в аргументе, об linux sleep 0.1 работает отлично - yael


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

1/2 секунды

 sleep 0.5

1/100 секунды

sleep 0.01

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

sleep 0.001

42
2018-01-15 13:24



Вы также можете сбросить начальный ноль до десятичной точки. например. sleep .5 - Mike Causer
За исключением mathforum.org/library/drmath/view/52352.html - stark


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

    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)

Комбинация Решение mr.spuratic а также решение колдов,


11
2018-06-22 19:52





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

usleep 1000

6
2017-07-08 13:55



$ usleep  No command 'usleep' found, did you mean:  Command 'sleep' from package 'coreutils' (main)  usleep: command not found - Bulletmagnet
Нет, я имею в виду usleep часть initscripts пакет, который является стандартным, по крайней мере, во всех дистрибутивах Red Hat; включая, по крайней мере, RHEL, CentOS, Fedora, Mageia / Mandriva и SuSE. Вот пример: `` `` - Luis Vazquez
Вот пример иллюстраций, запущенных в CentOS 7: `` `$, которые usleep / usr / bin / usleep $ rpm -qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64` `` Подведение итогов : - sleep (из Coreutils) работает с секундами - usleep (из Сценарии инициализации) работает с микросекундами - Luis Vazquez


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

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

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


2
2018-05-24 15:12



Ты мог как минимум изменить это usleep() позвонить if(argc == 1) { usleep(atoi(argv[1])); } чтобы избежать индексации вне границ массива, что может привести к любому количеству неожиданных действий. - Michael Kjörling