ENV:GNU bash,版本 4.2.46(2)-release (x86_64-redhat-linux-gnu) (它是旧的)
- 我希望每个循环都花费相同的时间。
- 循环永远不会停止
- 该
api_call
功能通常需要大约1s~5s。 - 由于网络问题,API 调用很少会挂到 60s-timeout。
我的脚本 A
TIMEFORMAT=%R
while true; do
time=$(date +'%F %T')
api_result=$( { time api_call; } 2>api_runtime.txt )
api_runtime=$(cat api_runtime.txt)
echo "${time} ${api_result}"
sleep (( 10 - ${api_runtime} ))
done
我认为 Scrit A 会完成这项工作,直到有一天网络变慢并且循环不同步。
我的脚本 B
TIMEFORMAT=%R
while true; do
time=$(date +'%F %T')
api_result=$( api_call & )
sleep 10
echo "${time} ${api_result:-No response}"
done
脚本 B 目前似乎也可以工作,但我不确定下一个循环在api_call
10 秒以上时是否安全。
我如何实现这一目标?
在命令替换内部使用
&
不会在后台与主脚本同时运行命令,只会在该命令替换中发生的其他事情。上面的作业在完成前会挂起两秒钟,下面的作业也是如此。
这意味着您
sleep 10
没有必要(或者更确切地说,它总是会在循环体的运行时间上增加 10 秒),因为在它之前的行上的分配将阻塞,直到它被执行,这将在api_call
终止时发生。如果您希望每次循环迭代花费 60 秒(您提到的超时长度):
这确保了分配将花费 60 秒,即使
api_call
在少于该时间后返回也是如此。或者,
...这需要 10 秒并显式发送一个 TERM 信号,
api_call
如果它比这慢。如果这是一个长时间运行的脚本,您会认为它会逐渐漂移。一个潜在的解决方案是使用 cron 作业以间隔重新安排它(杀死正在运行的脚本并重新执行它)。