如何在 POSIX shell 中随机休眠一秒?

发布于 2024-12-09 13:50:53 字数 1231 浏览 2 评论 0原文

以下内容不起作用:

/bin/sleep $(printf ".%02ds" $(( $RANDOM % 100 )))
  1. POSIX sleep 仅支持积分秒
  2. 没有 $RANDOM

我可以通过以下方式模拟随机:

RAND255=$(od -An -N1 -t u1 /dev/urandom)

另一种选择是编写一个利用 usleep()*rand*() 根据@dmckee@基思·汤普森。部署此类程序可能并不总是可行。

是否有更好的方法,即,除了手写的 C 程序之外,是否有 POSIX 中的睡眠替代方案可以接受秒的小数部分,并且是否有更好的方法来模拟 $RANDOM< /code> 除了 od

The following won't work:

/bin/sleep $(printf ".%02ds" $(( $RANDOM % 100 )))
  1. POSIX sleep supports only integral seconds
  2. there is no $RANDOM

I could emulate random by:

RAND255=$(od -An -N1 -t u1 /dev/urandom)

Another option is to write a small C program that utilizes usleep() and *rand*() as suggested by @dmckee and @Keith Thompson. Deploying such program might not be always possible.

Is there a better way i.e., is there an alternative for sleep in POSIX that accept fractions of a second other than a hand-written C program and is there a better way to emulate $RANDOM other than od?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苍景流年 2024-12-16 13:50:53

例如,在第一个命令中,如果 $RANDOM % 100 为 6,它将调用 /bin/sleep .6s;你需要/bin/sleep .06s

在第二个命令中,od -An -N1 -t u1 /dev/random 似乎打印了 0..255 范围内的数字——如果< code>/dev/random 熵耗尽。请改用 /dev/urandom

我会编写一个调用 usleep() 的小型 C 程序(假设编译它并部署可执行文件是可行的)。

编辑

据我所知,您的(更新的)问题的答案是否定的。

POSIX 不保证 /dev/urandom,因此您的 od 命令不能移植到所有 POSIX 系统。我不相信 POSIX 指定任何可以休眠小数秒的命令。它确实指定了 nanosleep() 函数,但如果您不一定能够部署 C 程序,则没有帮助。 POSIX awk 没有睡眠功能。 Perl 不是 POSIX。

您的选择是:(1) 仅休眠整秒,或 (2) 使用非便携式方法。

您在什么环境下需要这个?

In your first command, if $RANDOM % 100 is 6, for example, it will invoke /bin/sleep .6s; you want /bin/sleep .06s.

In the second command, od -An -N1 -t u1 /dev/random seems to print a number in the range 0..255 -- and the command itself can delay for a long time if /dev/random runs out of entropy. Use /dev/urandom instead.

I'd write a small C program that calls usleep() (assuming that compiling it and deploying the executable is feasible).

EDIT:

As far as I can tell, the answer to your (updated) question is no.

POSIX doesn't guarantee /dev/urandom, so your od command isn't portable to all POSIX systems. I don't believe POSIX specifies any command that can sleep for fractional seconds. It does specify the nanosleep() function, but if you can't necessarily deploy a C program that doesn't help. POSIX awk has no sleep function. Perl is not POSIX.

Your options are: (1) sleep only for whole seconds, or (2) use a non-portable method.

What environment(s) do you need this for?

魄砕の薆 2024-12-16 13:50:53

Perl 有 usleep 但在加载的系统上,加载时间可能比短睡眠时间占主导地位。

Perl has usleep but on a loaded system, load times probably dominate over short sleeps.

〗斷ホ乔殘χμё〖 2024-12-16 13:50:53

Cliff 随机数生成器是一个非常简单的随机数生成器,“通过不显示任何结构的随机性噪声球测试”。它很容易编程,只需不到 10 行 awk 代码:

 # cliff_rand.awk --- generate Cliff random numbers



 BEGIN { _cliff_seed = 0.1 }

 function cliff_rand()
 {
     _cliff_seed = (100 * log(_cliff_seed)) % 1
     if (_cliff_seed < 0)
         _cliff_seed = - _cliff_seed
     return _cliff_seed
 }

该算法需要 0.1 的初始“种子”。每个新值都使用当前种子作为计算的输入。如果内置 rand() 函数(请参阅数字函数)不够随机,您可以尝试使用此函数。

取自此处

The Cliff random number generator is a very simple random number generator that “passes the noise sphere test for randomness by showing no structure.” It is easily programmed, in less than 10 lines of awk code:

 # cliff_rand.awk --- generate Cliff random numbers



 BEGIN { _cliff_seed = 0.1 }

 function cliff_rand()
 {
     _cliff_seed = (100 * log(_cliff_seed)) % 1
     if (_cliff_seed < 0)
         _cliff_seed = - _cliff_seed
     return _cliff_seed
 }

This algorithm requires an initial “seed” of 0.1. Each new value uses the current seed as input for the calculation. If the built-in rand() function (see Numeric Functions) isn't random enough, you might try using this function instead.

Taken from here

海未深 2024-12-16 13:50:53

这个解决方案通过轮询单调计数器 /proc/uptime 在 Linux 上工作 - 它甚至可以在 1/100 秒的慢速系统上工作:

#!/bin/sh

WAIT=567        # 5.67 sec

get_up()
{
        read -r UP REST </proc/uptime
        export UP=${UP%.*}${UP#*.}
}

get_up; START=$UP
while :; do get_up; test $((UP-START)) -ge $WAIT && break; done

一个快速而肮脏的 oneliner (复制/粘贴!)在这里:

W=567;x(){ read U R </proc/uptime;U=${U%.*}${U#*.};};x;S=$U;while :;do x;test $((U-S)) -ge $W && break;done

this solution works on linux by polling the monotonic counter /proc/uptime - it works even on slow systems for 1/100 of a second exact:

#!/bin/sh

WAIT=567        # 5.67 sec

get_up()
{
        read -r UP REST </proc/uptime
        export UP=${UP%.*}${UP#*.}
}

get_up; START=$UP
while :; do get_up; test $((UP-START)) -ge $WAIT && break; done

A quick and dirty oneliner (copy/paste!) is here:

W=567;x(){ read U R </proc/uptime;U=${U%.*}${U#*.};};x;S=$U;while :;do x;test $((U-S)) -ge $W && break;done
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文