我如何在 bash 或 ksh 中睡眠一毫秒

yae*_*ael 163 linux solaris bash ksh shell-scripting

sleep 是一个非常流行的命令,我们可以从 1 秒开始睡眠:

# wait one second please 
sleep 1
Run Code Online (Sandbox Code Playgroud)

但是如果我只需要等待 0.1 秒或在 0.1 到 1 秒之间,还有什么选择?

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

sca*_*cai 157

coreutilssleep命令的文档说:

sleep 的历史实现要求该数字是一个整数,并且只接受一个没有后缀的参数。但是,GNU sleep 接受任意浮点数。请参阅 浮点数

因此,您可以使用sleep 0.1,sleep 1.0e-1和类似的参数。


mr.*_*tic 79

Bash 有一个“可加载”睡眠,它支持小数秒,并消除了外部命令的开销:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep
Run Code Online (Sandbox Code Playgroud)

然后:

$ 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
Run Code Online (Sandbox Code Playgroud)

缺点是你的bash二进制文件可能没有提供可加载文件,所以你需要自己编译它们,如图所示(尽管在 Solaris 上它不一定像上面那样简单)。

截至bash-4.4(2016 年 9 月),所有可加载文件现在默认构建并安装在支持它的平台上,尽管它们是作为单独的共享对象文件构建的,并且没有.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
Run Code Online (Sandbox Code Playgroud)

(手册页暗示BASH_LOADABLES_PATH是自动设置的,我发现在 4.4.12 的官方发行版中并非如此。如果设置正确,您只需要enable -f filename commandname根据需要。)

如果这不合适,下一个最简单的方法是sleep从 GNU coreutils构建或获取,这支持所需的功能。POSIXsleep命令是最小的,旧的 Solaris 版本仅实现了这一点。Solaris 11sleep 确实支持小数秒。

作为最后的手段,您可以使用perl(或您必须使用的任何其他脚本),但需要注意的是,初始化解释器可能与预期的睡眠时间相当:

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh
Run Code Online (Sandbox Code Playgroud)

  • 啊,由于您使用的是 `expect`,您可能可以直接在脚本中使用“`after N`”,其中 N 是毫秒。 (2认同)

col*_*ete 69

Sleep 接受十进制数,因此您可以将其分解如下:

1/2 秒

 sleep 0.5
Run Code Online (Sandbox Code Playgroud)

1/100 秒

sleep 0.01
Run Code Online (Sandbox Code Playgroud)

所以一毫秒你会想要

sleep 0.001
Run Code Online (Sandbox Code Playgroud)

  • 您还可以删除小数点前的前导零。例如。`睡眠0.5` (4认同)
  • 除了 http://mathforum.org/library/drmath/view/52352.html (2认同)
  • @MikeCauser 前导零更具可读性,并在以后向代码的读者发出信号意图。当你真正做数学时也会更好。 (2认同)

小智 13

试试这个来确定准确性:

    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)
Run Code Online (Sandbox Code Playgroud)

结合mr.spuratic的解决方案科尔斯的解决方案


小智 12

您可以简单地使用usleep. 它需要微秒(= 1e-6 秒)作为参数,因此要休眠 1 毫秒,您将输入:

usleep 1000
Run Code Online (Sandbox Code Playgroud)

  • `$ usleep` `未找到命令 'usleep',您的意思是:` `来自包 'coreutils'(主)的命令 'sleep'` `usleep:未找到命令` (2认同)

小智 5

我遇到了同样的问题(Solaris 上没有 shell usleep)所以我自己写了这样的:

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

不检查参数 - 如果你想保留它,我会推荐一个正确编写的参数,但是 (gcc usleep.c -o usleep) 会让你摆脱困境。