题 我如何以bash或ksh睡眠一毫秒


睡眠是一个非常受欢迎的命令,我们可以从1秒钟开始睡眠:

# wait one second please 
sleep 1

但如果我需要等待0.1秒或0.1到1秒之间的替代方案呢?

  • 备注:在linux或OS X上 sleep 0.XXX 工作正常,但在solaris上 sleep 0.1 要么 sleep 0.01  - 非法语法

105
2018-01-15 13:19




我可以问你为什么要睡1ms? - Tom O'Connor
是的当然,在我的bash脚本中我添加了“sleep 1”,在某些行中,但是脚本运行得非常慢,所以经过一些结论后我计算出睡眠0.1也带来了好的结果和更快的关于延迟,我需要延迟顺序为了解决我的bash脚本中的ssh问题,我执行了对某些机器的paralel ssh登录,并且没有延迟它将无法工作,正如你从我的问题中所知,延迟应该适合Linux和Solaris - yael
无论您选择哪种解决方案,请记住,shell脚本在时间方面不会非常准确。 - scai
做一些需要很短时间才能执行但却什么也不做的事情 echo "" >/dev/null - Tom O'Connor
好主意,但这个命令如何msec? ,我需要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年9月)所有可加载项现在默认构建并安装在支持它的平台上,尽管它们是作为单独的共享对象文件构建的,并且没有 .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

59
2018-01-15 13:52



啊,因为你正在使用 expect 你可以只使用“after N“,其中N是毫秒,直接在您的脚本中。 - mr.spuratic
使用 usleep 比如@Luis Vazquez和@sebix写的 - Ilan.K


的文档 sleep 命令来自 的coreutils 说:

睡眠的历史实现要求该数字为a   整数,只接受没有后缀的单个参数。   但是,GNU sleep接受任意浮点数。看到    浮点

因此你可以使用 sleep 0.1sleep 1.0e-1 和类似的论点。


103
2018-01-15 13:22



看看我对SOLARIS OS的评论 - yael
你混淆了吗 是 和 不? - scai
在我的问题中查看我的更新 - yael
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

46
2018-01-15 13:24



您也可以删除小数点前的前导零。例如。 sleep .5 - Mike Causer
除了 mathforum.org/library/drmath/view/52352.html - stark
谈论其他所有人过于复杂的事情...... - Martin


试试这个来确定准确性:

    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。它需要微秒(= 1e-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中运行的示例ilustration:```$ 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上没有shell),所以我写了自己的问题:

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

不检查参数 - 如果你想保留它,我建议你写一个正确的参数但是(gcc usleep.c -o usleep)会让你走出困境。


3
2018-05-24 15:12



你可以 至少 改变那种光 usleep() 拨电至 if(argc == 1) { usleep(atoi(argv[1])); } 避免在数组边界之外进行索引,这可能导致任意数量的意外行为。 - α CVn