每 X 秒执行一次命令

每 X 秒执行一次命令

我希望每 10 秒执行一次命令,并让它在后台执行(从而消除watch?)。所有答案都显示如下内容,但这将执行 11 到 14 秒。如何才能做到这一点?

while true; do
    # perform command that takes between 1 and 4 seconds
    sleep 10
done

答案1

怎么样:

( # In a subshell, for isolation, protecting $!
  while true; do
    perform-command & # in the background
    sleep 10 ;
    ### If you want to wait for a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line:
    # wait $! ;
    ### If you prefer to kill a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line instead:
    # kill $! ;
    ### (If you prefer to ignore it, uncomment neither.)
  done
)

ETA:有了所有这些评论、替代方案和用于额外保护的子 shell,这看起来比开始时要复杂得多。因此,为了进行比较,以下是我开始担心waitkill以及它们的$!隔离需求之前的情况:

while true; do perform-command & sleep 10 ; done

其余的只是在您需要时使用。

答案2

bash您可以在、zsh或中执行类似以下操作ksh

SECONDS=0
while   command
do      sleep "$((10-(SECONDS%10)))"
done

这是bash手册的内容$SECONDS

$SECONDS

  • 每次引用此参数时,都会返回自 shell 调用以来的秒数。如果将值分配给$SECONDS,则后续引用时返回的值是自分配以来的秒数加上所分配的值。如果$SECONDSunset,它就会失去其特殊属性,即使它随后被重置。

这是一个工作示例:

(   SECONDS=0
    while   sleep   "$((RANDOM%10))"
    do      sleep   "$((10-(SECONDS%10)))"
            echo    "$SECONDS"
    done
)

10
20
30
40
50
60
70
80
90
100

答案3

仅限 BASH - 您还可以计算命令所花费的时间并从 10 中减去:

TIMEFORMAT=$'%0R'
while true; do
    T=$({ time command; } 2>&1)
    sleep $(( 10-T ))

来自 BASH 人:

TIMEFORMAT 此参数的值用作格式字符串,指定应如何显示以时间保留字为前缀的管道的计时信息。 % 字符引入了扩展为时间值或其他信息的转义序列。转义序列及其含义如下;大括号表示可选部分。
%% 字面量 %。
%[p][l]R 经过的时间(以秒为单位)。
%[p][l]U 在用户模式下花费的 CPU 秒数。
%[p][l]S 在系统模式下花费的 CPU 秒数。
%P CPU 百分比,计算公式为 (%U + %S) / %R。

可选的 p 是指定精度的数字,即小数点后的小数位数。值为 0 会导致不输出小数点或分数。

相关内容