Как мне спать в течение миллисекунды в 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
добавляет поддержку действительных чисел, суффиксов, даже научных обозначений иinf
inity как расширения GNU . Но если вы используете встроенную систему сbusybox
или у вас просто нет coreutils, тогда вам не повезло, если у вас нет Perl.
perl -e 'select(undef, undef, undef, 0.1);'