如何在bash中创建秒表?

时间:2016-06-23 08:46:51

标签: bash math time timer bash-function

我创建了一个简单的秒表(bash函数)来计算时间,但是现在它以毫秒为单位显示当前时间。

代码:

function stopwatch() {
    date +%H:%M:%S:%N
    while true; do echo -ne "`date +%H:%M:%S:%N`\r"; done;
}

我尝试按this answer中的说明更改它,但它仅适用于自Unix Epoch以来的第二个。

当我使用date格式+%s.%N时,由于bash减法仅使用整数,因此上述答案的减法停止了工作。

我该如何解决它,并有一个终端秒表打印时间如下:

0.000000000
0.123123123
0.435345345
(and so on..)

7 个答案:

答案 0 :(得分:8)

如果你想要一些简单的东西,包括分钟,秒和厘秒,就像传统的秒表一样,你可以使用sw

sw

安装

wget -q -O - http://git.io/sinister | sh -s -- -u https://raw.githubusercontent.com/coryfklein/sw/master/sw

用法

# start a stopwatch from 0, save start time in ~/.sw
sw

# resume the last run stopwatch
sw --resume 

答案 1 :(得分:5)

一种可行的(&hacky)机制可以工作一天:

$ now=$(date +%s)sec
$ while true; do
     printf "%s\r" $(TZ=UTC date --date now-$now +%H:%M:%S.%N)
     sleep 0.1
  done

注意:这是一个快速解决方法。应该有更好的解决方案......

答案 2 :(得分:1)

这是我之前抓到的一个更好的功能:

function stopwatch() {
    local BEGIN=$(date +%s)
    echo Starting Stopwatch...

    while true; do
        local NOW=$(date +%s)
        local DIFF=$(($NOW - $BEGIN))
        local MINS=$(($DIFF / 60))
        local SECS=$(($DIFF % 60))
        local HOURS=$(($DIFF / 3600))
        local DAYS=$(($DIFF / 86400))

        printf "\r%3d Days, %02d:%02d:%02d" $DAYS $HOURS $MINS $SECS
        sleep 0.5
    done
}

答案 3 :(得分:1)

这是我的:

time cat

您按Ctrl-c或Ctrl-d可以停止并显示时间。第一个数字是时间。

我将其进一步完善为这个bash别名

alias stopwatch="echo Press Ctrl-c to stop the timer; TIMEFORMAT=%R; time cat; unset TIMEFORMAT"

答案 4 :(得分:0)

对于减法,您应使用bcAn arbitrary precision calculator language)。

以下是满足您要求的示例代码:

function stopwatch() {
    date1=`date +%s.%N`
    while true; do
        curr_date=`date +%s.%N`
        subtr=`echo "$curr_date - $date1" | bc`
        echo -ne "$subtr\r";
        sleep 0.03
    done;
}

添加了额外的sleep以降低CPU使用率(在我的计算机上没有它几乎是15%,而sleep它降低到1%)。

答案 5 :(得分:0)

基于a gist by rawaludin

function stopwatch() {
  local BEGIN=$(date +%s)

  while true; do
    local NOW=$(date +%s)
    local DIFF=$(($NOW - $BEGIN))
    local MINS=$(($DIFF / 60 % 60))
    local SECS=$(($DIFF % 60))
    local HOURS=$(($DIFF / 3600 % 24))
    local DAYS=$(($DIFF / 86400))
    local DAYS_UNIT
    [ "$DAYS" == 1 ] && DAYS_UNIT="Day" || DAYS_UNIT="Days"

    printf "\r  %d %s, %02d:%02d:%02d  " $DAYS $DAYS_UNIT $HOURS $MINS $SECS
    sleep 0.25
  done
}

对于不熟悉这一点的人:在英语中,只有在1时我们才会使用单数 - 日。当它是0,2,3,4,5 ......时,我们使用复数  " Days",请注意它是0 Days

答案 6 :(得分:0)

这是bash秒表的另一种说法,该线程的其他答案也有很多借鉴意义。此版本与其他版本不同的方式包括:

  • 此版本使用bash算术,而不是调用bc,我发现(通过计时)它的CPU时间更少。
  • 我已经解决了有人指出的25小时限制,即在每天经过的小时部分增加24小时。 (所以现在我想这是〜31天的限制。)
  • 与接受的答案中的版本不同,我将光标留在输出的右侧。这样一来,您只需按Enter键即可轻松测量圈数(或更通常地标记重要的事件时间),这会将计时器移至下一行,从而使按键时间保持可见。
#!/bin/bash

start_time=$(date +%s)

while true; do
  current_time=$(date +%s)
  seconds_elapsed=$(( $current_time - $start_time ))
  timestamp=$(date -d"@$seconds_elapsed" -u +%-d:%-H:%-M:%-S)

  IFS=':' read -r day hour minute second <<< "$timestamp"
  hour="$(( $hour+24*($day-1) ))"

  printf "\r%02d:%02d:%02d" $hour $minute $second
  sleep 0.5
done;

以下是运行stopwatch(作为PATH中的可执行脚本)并在7和18秒处按返回键,并在大约9分钟后按Ctrl-C时输出的示例输出:

$ stopwatch
00:00:07
00:00:18
00:09:03^C
$

注意:

  • 我将+%-d:%-H:%-M:%-S输出格式用于日期(此破折号表示“请删除任何前导零”),因为printf似乎将前导零的数字字符串解释为八进制,最终抱怨无效值。
  • li>
  • 我摆脱了纳秒级的原因仅仅是因为出于我的目的,我不需要超过1秒的精度。因此,我将sleep的持续时间调整为更长,以节省计算时间。