【问题标题】:bash timer in milliseconds以毫秒为单位的 bash 计时器
【发布时间】:2017-07-10 10:12:13
【问题描述】:

我正在尝试以毫秒为单位实现 5 分钟(300 秒)的计时器,但睡眠 0.001 需要超过 5 分钟。

如果我将 if [ $t -ge 300000 ] 更改为 if [ $t -ge 30000 ],它将在 3 分钟内完成。

df1, df2 分别保存 t1 和 t2 时刻的磁盘使用率值。

t=0
x=0
df1
    while [ $x -lt 10000 ]

        sleep 0.001
        df2
        x=(( df1-df2 ))
        if [ $t -ge 300000 ]
        then
        t=0
        df1            
        else
        (( t++ ))
        fi
    done
dosomething

我想每 0.001 秒测试一次 $xdf1df2 应该每 300 秒保存一次新值。我怎样才能做到这一点?

【问题讨论】:

  • Zaheer:不清楚你的完整需求,为什么不直接写sleep 300(for 5 mins)呢?
  • 为什么不只是sleep 300?如果您确实需要以如此快的速度进行迭代(即非常短的睡眠间隔,并且可能解释了持续时间的漂移),您应该将比较基于读取当前时间并与之前的时间进行比较,而不是睡眠预定的持续时间并增加一个计数器。为此,您可以使用date +%s 根据系统时钟获取以秒为单位的递增计数器。
  • 我需要监控每 t(0.001) 秒的磁盘使用情况,如果在 300000 秒内有任何巨大差异($x),它应该采取一些措施。如果我使用 sleep 300,脚本将处于空闲状态,并且在此期间不会监控 df。我想迅速采取行动,因此是 0.001。
  • 由于你的循环条件是[ $x -lt 10000 ],如果不知道df1df2 的实际值是什么,就很难判断循环何时结束。我能提供的最好建议是sleep 0.001 可能不太准确。
  • 可能值得考虑创建一个小型 C 程序来进行更精确的计算。看到这个帖子的答案stackoverflow.com/questions/10192903/time-in-milliseconds

标签: linux bash shell


【解决方案1】:

日期 %N,将以纳秒为单位获取时间,也许这有帮助

start_at=$(date +%s,%N)
_s1=$(echo $start_at | cut -d',' -f1)   # sec
_s2=$(echo $start_at | cut -d',' -f2)   # nano sec
# do somethong here
end_at=$(date +%s,%N)
_e1=$(echo $end_at | cut -d',' -f1)
_e2=$(echo $end_at | cut -d',' -f2)
time_cost=$(bc <<< "scale=3; $_e1 - $_s1 + ($_e2 -$_s2)/1000000000")

【讨论】:

    【解决方案2】:

    我敢肯定,像你这样的一次睡眠不需要几分钟。虽然它可以而且通常会花费比您请求的毫秒更长的时间,但实际睡眠时间仍应远低于 1 秒,或者,如果系统负载很重,最多为几秒。

    您的应用程序中的一个缺陷是您没有考虑循环的一次迭代需要多长时间。您无法提前知道这一点;你只知道它会超过一毫秒,但不知道多长时间。因此,您应该在经过一定时间后结束循环 - 即将开始时间存储在某处并将当前时间与开始时间进行比较。

    第二个问题是您没有在任何地方设置变量 df1 和 df2,但也许您忽略了这个细节,因为您认为它与您的问题无关。

    【讨论】:

      【解决方案3】:

      如果您正在寻找显示毫秒的倒数计时器,那么您正在寻找这个。

      这将计时器显示为百分之一秒。

      根据需要更改逻辑。

          timer() {
          time="`date '+%H:%M:%S' -d "$1"`"
          if [ $# -gt 0 ] && [ "$1" = "$time" ]; then
              echo 
              IFS=:
              set -- $*
              secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
              while [ $secs -ge 0 ]; do
                      for msec in {99..0}; do
                      printf "\rCountdown Timer: %02d:%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))  $((msec))
                      sleep .01
                      done
                      secs=$(( $secs - 1 ))
              done
              echo
          fi
          echo 
          }
      
          Usage: # timer HH:MM:SS
          Where: HH  Time in Hours
                 MM  Time in Mins
                 SS  Time in Secs
          Example: 
                 # timer 00:10:00 
                 Sets a countdown timer for 10 mins while displaying hundredth of a second.
      

      【讨论】:

      • 根本无法保证sleep 0.01 只会在给定的持续时间内休眠——如果是操作系统安排它的时间,它可以休眠更长的时间,并且该延迟将累加多个/后续来电。
      • 我同意。它对我来说工作得很好,高达百分之一秒。我注意到滞后几毫秒甚至更多......
      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-12
      • 2012-11-15
      相关资源
      最近更新 更多