Max*_*axG 13 sleep shell-script
我是 bash 脚本的新手,从一些示例脚本开始。
一种是:
#!/bin/bash
SECONDS=5
i=1
while true
do
echo "`date`: Loop $i"
i=$(( $i+1 ))
sleep $SECONDS
done
Run Code Online (Sandbox Code Playgroud)
这导致:
Sunday 10 May 15:08:20 AEST 2020: Loop 1
Sunday 10 May 15:08:25 AEST 2020: Loop 2
Sunday 10 May 15:08:35 AEST 2020: Loop 3
Sunday 10 May 15:08:55 AEST 2020: Loop 4
Run Code Online (Sandbox Code Playgroud)
...并且不是我期望或希望脚本做的。
为什么每次运行循环时秒数都会加倍
bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
Run Code Online (Sandbox Code Playgroud)
ImH*_*ere 26
因为SECONDS是 bash 中的内部变量。它存储外壳程序运行的时间量。
来自man bash:
SECONDS
每次引用此参数时,都会返回自调用 shell 以来的秒数。如果将值分配给 SECONDS,则后续引用返回的值是自分配以来的秒数加上分配的值。
所以,你的脚本是这样工作的:
这个结构有一个二阶问题:如果循环中的处理需要大量时间(比如 1.4 秒),那么循环只会每 6.4 秒重复一次。
如果这很重要,您可以改为计算循环次数。
#!/bin/bash
Expired=$(( SECONDS + 23 ))
Tick=5
Iter=1
while (( SECONDS < Expired )); do
echo "$(date '+%T.%N'): Loop $Iter"
sleep 1.4 #.. Simulate work.
echo "$(date '+%T.%N'): Idle"
sleep $(( Iter++ * Tick - SECONDS ))
done
Run Code Online (Sandbox Code Playgroud)
循环时间在 SECONDS 的整数精度内是稳定的。
您可以执行更复杂的算术来初始化 Expired(例如,使用两个日期命令来查找午夜之前的秒数)。