2013-06-24 20:13:51 +0000 2013-06-24 20:13:51 +0000
157
157

有没有办法在终端中显示倒计时或秒表计时器?

如何在Linux终端上显示实时倒计时器?有没有现成的应用,或者更好的,一字型的应用来实现这个功能?

答案 (22)

195
195
195
2013-06-24 22:11:13 +0000

我不知道你为什么需要beep,如果你想要的只是一个秒表,你可以这样做。

while true; do echo -ne "`date`\r"; done

这样就能显示出实时的秒数,你可以用Ctrl+C停止它。如果你需要更高的精度,你可以用这个来给你纳秒。

while true; do echo -ne "`date +%H:%M:%S:%N`\r"; done

最后,如果你真的,真的想要 “秒表格式",一切从0开始,然后开始增长,你可以这样做:

date1=`date +%s`; while true; do 
   echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
done

对于一个倒计时的计时器(这不是你最初的问题所要求的),你可以这样做(相应地改变秒数):

seconds=20; date1=$((`date +%s` + $seconds)); 
while ["$date1" -ge `date +%s`]; do 
  echo -ne "$(date -u --date @$(($date1 - `date +%s` )) +%H:%M:%S)\r"; 
done

你可以通过使用bash(或者任何你喜欢的shell)函数将这些命令组合成简单的命令。在bash中,将这些行添加到你的~/.bashrc中(sleep 0.1会让系统在每次运行之间等待1/10秒,这样你就不会浪费你的CPU)。

function countdown(){
   date1=$((`date +%s` + $1)); 
   while ["$date1" -ge `date +%s`]; do 
     echo -ne "$(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r";
     sleep 0.1
   done
}
function stopwatch(){
  date1=`date +%s`; 
   while true; do 
    echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r"; 
    sleep 0.1
   done
}

然后你可以通过运行:

countdown 60

来启动一分钟的倒计时器。

countdown $((2*60*60))

或者使用以下命令进行一整天的倒计时:

countdown $((24*60*60))

stopwatch

启动秒表:

countdown(){
    date1=$((`date +%s` + $1));
    while ["$date1" -ge `date +%s`]; do 
    ## Is this more than 24h away?
    days=$(($(($(( $date1 - $(date +%s))) * 1 ))/86400))
    echo -ne "$days day(s) and $(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r"; 
    sleep 0.1
    done
}
stopwatch(){
    date1=`date +%s`; 
    while true; do 
    days=$(( $(($(date +%s) - date1)) / 86400 ))
    echo -ne "$days day(s) and $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
    sleep 0.1
    done
}
  • *

如果你需要能够处理天以及小时、分钟和秒,你可以这样做。

0x1&

_注意,stopwatch功能还没有测试过几天,因为我真的不想等24小时。它应该能用,但如果不能用,请告诉我。

100
100
100
2015-03-30 08:26:08 +0000

我最喜欢的方式是:

开始。

time cat

停止:

ctrl+c
  • *

正如@wjandrea在下面评论的那样,另一个版本是运行:

time read

然后按Enter停止。

46
46
46
2014-06-06 07:06:57 +0000

我也在寻找同样的东西,最后用Python写了一些更复杂的东西。

这将给你一个简单的10秒倒计时。

sudo pip install termdown
termdown 10

Source: https://github.com/trehn/termdown

14
14
14
2016-11-03 19:06:37 +0000
sh-3.2# man leave

设置定时器15分钟

sh-3.2# leave +0015
Alarm set for Thu Nov 3 14:19:31 CDT 2016. (pid 94317)
sh-3.2#

编辑:我打开了一堆链接,我以为这是osx特有的,抱歉。留下我的答案,让其他人知道在BSD上的离开。

13
13
13
2013-06-26 19:52:03 +0000

我用过这个。

countdown()
(
  IFS=:
  set -- $*
  secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
  while [$secs -gt 0]
  do
    sleep 1 &
    printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))
    secs=$(( $secs - 1 ))
    wait
  done
  echo
)

例子:

countdown "00:07:55"

这里有一个

6
6
6
2013-12-29 05:42:56 +0000

这是以百分之一秒为单位的秒表:

#!/usr/bin/awk -f
function z() {
  getline < "/proc/uptime"
  close("/proc/uptime")
  return $0
}
BEGIN {
  x = z()
  while (1) {
    y = z()
    printf "%02d:%05.2f\r", (y - x) / 60, (y - x) % 60
  }
}

示例

5
5
5
2019-06-05 10:48:15 +0000

简答。

for i in `seq 60 -1 1` ; do echo -ne "\r$i " ; sleep 1 ; done

解释:

我知道有很多答案,但我只想贴出与OP的问题非常接近的东西,我个人认为确实是 “终端的单行线倒计时"。我的目标是

1 一句话: 2. 2.倒计时。 3. 易于记忆和在控制台中打字(没有函数和重逻辑,只有bash)。 4. 不需要安装额外的软件(可以在我通过ssh去的任何服务器上使用,即使我在那里没有root)。

工作原理。

  1. seq打印从60到1的数字
  2. echo -ne "\r$i "返回到字符串的开头并打印当前的$i值。后面的空格是用来覆盖之前的值,如果它比当前的$i长一个字符(10 -> 9)。
4
4
4
2015-02-01 14:42:54 +0000

我结合了非常好的 terdon 的答案,将其转化为同时显示从开始到结束的时间的函数,也有三个变体,所以更容易调用 (你不必做 bash 数学运算),而且它也是抽象的。也有三个变体,所以更容易调用(你不必做bash数学),而且它也是抽象的。使用实例

{ ~ } » time_minutes 15
Counting to 15 minutes
Start at 11:55:34 Will finish at 12:10:34
     Since start: 00:00:08 Till end: 00:14:51

还有一些类似工作计时器的东西:

{ ~ } » time_hours 8
Counting to 8 hours
Start at 11:59:35 Will finish at 19:59:35
     Since start: 00:32:41 Till end: 07:27:19

如果你需要一些非常具体的时间:

{ ~ } » time_flexible 3:23:00
Counting to 3:23:00 hours
Start at 12:35:11 Will finish at 15:58:11
     Since start: 00:00:14 Till end: 03:22:46

这里是代码,可以放到你的.Bashrc中。 bashrc

function time_func()
{
   date2=$((`date +%s` + $1));
   date1=`date +%s`;
   date_finish="$(date --date @$(($date2)) +%T )"

   echo "Start at `date +%T` Will finish at $date_finish"

    while ["$date2" -ne `date +%s`]; do
     echo -ne " Since start: $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S) Till end: $(date -u --date @$(($date2 - `date +%s`)) +%H:%M:%S)\r";
     sleep 1
    done

    printf "\nTimer finished!\n"
    play_sound ~/finished.wav
}

function time_seconds()
{
  echo "Counting to $1 seconds"
  time_func $1
}

function time_minutes()
{
  echo "Counting to $1 minutes"
  time_func $1*60
}

function time_hours()
{
  echo "Counting to $1 hours"
  time_func $1*60*60
}

function time_flexible() # accepts flexible input hh:mm:ss
{
    echo "Counting to $1"
    secs=$(time2seconds $1)
    time_func $secs
}

function play_sound() # adjust to your system
{
    cat $1 > /dev/dsp
}

function time2seconds() # changes hh:mm:ss to seconds, found on some other stack answer
{ 
    a=( ${1//:/ }) 
    echo $((${a[0]}*3600+${a[1]}*60+${a[2]})) 
}

把它和一些在linux终端中播放声音的方法结合起来通过Linux命令行播放mp3或wav文件)或cygwin(cat /path/foo.wav > /dev/dsp在babun/win7中为我工作),你就有了一个简单灵活的带闹钟的定时器!

3
3
3
2013-06-25 00:40:38 +0000

我最后写了我自己的shell脚本。github gist

#!/bin/sh
# script to create timer in terminal
# Jason Atwood
# 2013/6/22

# start up
echo "starting timer script ..."
sleep 1 # seconds

# get input from user
read -p "Timer for how many minutes?" -e DURATION
DURATION=$(( $DURATION*60 )) # convert minutes to seconds

# get start time
START=$(date +%s)

# infinite loop
while [-1]; do
clear # clear window

# do math
NOW=$(date +%s) # get time now in seconds
DIF=$(( $NOW-$START )) # compute diff in seconds
ELAPSE=$(( $DURATION-$DIF )) # compute elapsed time in seconds
MINS=$(( $ELAPSE/60 )) # convert to minutes... (dumps remainder from division)
SECS=$(( $ELAPSE - ($MINS*60) )) # ... and seconds

# conditional
if [$MINS == 0] && [$SECS == 0] # if mins = 0 and secs = 0 (i.e. if time expired)
then # blink screen
for i in `seq 1 180`; # for i = 1:180 (i.e. 180 seconds)
do
clear # flash on
setterm -term linux -back red -fore white # use setterm to change background color
echo "00:00 " # extra tabs for visibiltiy

sleep 0.5

clear # flash off
setterm -term linux -default # clear setterm changes from above
echo "00:00" # (i.e. go back to white text on black background)
sleep 0.5
done # end for loop
break # end script

else # else, time is not expired
echo "$MINS:$SECS" # display time
sleep 1 # sleep 1 second
fi # end if
done # end while loop
```。
3
3
3
2016-11-24 15:38:57 +0000

我很惊讶,没有人在他们的脚本中使用sleepenh工具。相反,提出的解决方案要么在后续的定时器输出之间使用sleep 1,要么使用一个尽可能快的输出的忙循环。前者是不够的,因为由于做打印的时间很小,实际上不会每秒输出一次,而是少了一点,这是次优的。时间过够后,计数器会跳过一秒。后者是不够的,因为它会让CPU无端忙碌。

我的$PATH里的工具是这样的。

#!/bin/sh
if [$# -eq 0]; then
    TIMESTAMP=$(sleepenh 0)
    before=$(date +%s)
    while true; do
        diff=$(($(date +%s) - before))
        printf "%02d:%02d:%02d\r" $((diff/3600)) $(((diff%3600)/60)) $((diff%60))
        TIMESTAMP=$(sleepenh $TIMESTAMP 1.0);
    done
    exit 1 # this should never be reached
fi
echo "counting up to $@"
"$0" &
counterpid=$!
trap "exit" INT TERM
trap "kill 0" EXIT
sleep "$@"
kill $counterpid

这个脚本既可以作为一个停表(一直到中断为止),也可以作为一个定时器,在指定时间内运行。由于使用了 sleep 命令,这个脚本允许指定持续时间,其精度与 sleep 允许的一样。在Debian和衍生产品上,这包括亚秒级的睡眠和一个很好的人类可读的方式来指定时间。例如,您可以说

$ time countdown 2m 4.6s
countdown 2m 4.6s 0.00s user 0.00s system 0% cpu 2:04.60 total

正如你所看到的,这个命令精确地运行了2分4. 6秒,脚本本身并没有太多魔法。

编辑

sleepenh工具来自Debian及其衍生版本(如Ubuntu)的同名软件包。对于没有这个工具的发行版,它来自 https://github.com/nsc-deb/sleepenh

sleepenh的优势在于,它能够考虑到循环过程中除了睡眠之外的其他事情处理所累积的小延迟。即使只是在循环中sleep 1 10次,由于执行sleep和循环迭代带来的小开销,整体执行时间会超过10秒。这个错误会慢慢积累,随着时间的推移,会让我们的秒表计时器越来越不精确。为了解决这个问题,必须每次循环迭代都要计算出精确的睡眠时间,这个时间通常略小于一秒(对于一秒区间定时器)。sleepenh工具可以帮你完成这个任务。

3
3
3
2014-08-21 19:13:05 +0000

另一种方法

countdown=60 now=$(date +%s) watch -tpn1 echo '$((now-$(date +%s)+countdown))'

For Mac。

countdown=60 now=$(date +%s) watch -tn1 echo '$((now-$(date +%s)+countdown))'
#no p option on mac for watch

如果想在零点时得到一个信号,可以用一个在零点时返回非零退出状态的命令来建立,然后结合watch -b之类的,但如果想建立一个更复杂的脚本,这可能不是办法;它更像是一个 “快速而肮脏的单行本 "类型的解决方案。


我总体上喜欢watch这个程序。我第一次看到它,是在我已经写了无数个while sleep 5; do循环到不同效果之后。watch是明显的比较好的。

3
3
3
2017-06-23 21:06:54 +0000

sw 是一个简单的秒表,它将永远运行。

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

安装

sw
 - start a stopwatch from 0, save start time in ~/.sw
sw [-r|--resume]
 - start a stopwatch from the last saved start time (or current time if no last saved start time exists)
 - "-r" stands for --resume

使用方法

1
1
1
2015-04-13 12:34:57 +0000

假设你是一个在OSX上寻找命令行秒表的人。假设你不想安装gnu工具,只想用unix date

运行,这样的话,就按照@terdon说的做,但要做如下修改。

function stopwatch(){
    date1=`date +%s`; 
    while true; do 
        echo -ne "$(date -jf "%s" $((`date +%s` - $date1)) +%H:%M:%S)\r"; 
        sleep 0.1
    done
}
1
1
1
2019-04-13 14:58:34 +0000

看看 TermTime ,这是一个不错的基于终端的时钟和秒表。

pip install termtime

1
1
1
2015-06-02 01:12:11 +0000

只需使用手表+日期的UTC时间。你也可以安装一些大显示屏的软件包……

export now="`date +%s -u`";
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now ))'

#Big plain characters
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now )) | toilet -f mono12'

#Big empty charaters
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now )) | figlet -c -f big'

试试吧!

参见 http://www.cyberciti.biz/faq/create-large-colorful-text-banner-on-screen/

1
1
1
2014-09-26 15:21:48 +0000

为了便于将来参考,有一个名为 µTimer 的命令行工具,它有非常直接的命令行选项,用于倒计时/倒计时。

1
1
1
2014-02-13 12:00:38 +0000

一个python的例子:

#!/usr/bin/python

def stopwatch ( atom = .01 ):
    import time, sys, math

    start = time.time()
    last = start
    sleep = atom/2
    fmt = "\r%%.%sfs" % (int(abs(round(math.log(atom,10)))) if atom<1 else "")
    while True:
        curr = time.time()
        subatom = (curr-last)
        if subatom>atom:
            # sys.stdout.write( "\r%.2fs" % (curr-start))
            sys.stdout.write( fmt % (curr-start))
            sys.stdout.flush()
            last = curr
        else:
            time.sleep(atom-subatom)

stopwatch()

0
0
0
2018-11-05 13:49:26 +0000

GUI版本的秒表

date1=`date +%s`
date1_f=`date +%H:%M:%S ____ %d/%m`
(
  while true; do 
    date2=$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)
    echo "# started at $date1_f \n$date2"
  done
) |
zenity --progress \
  --title="Stop Watch" \
  --text="Stop Watch..." \
  --percentage=0
```。
0
0
0
2016-12-08 20:20:14 +0000

今天早些时候,当我在寻找一个术语应用程序来显示一个大型的倒计时计时器时,发现了这个问题。所有的建议都不是我所需要的,所以我很快就在Go中又做了一个。https://github.com/bnaucler/cdown

由于这个问题已经得到了充分的回答,所以为了方便后人,就把它放在这里吧。

0
0
0
2017-01-24 23:04:07 +0000

$ sleep 1500 && xterm -fg yellow -g 240x80 &

当那个带着黄色文字的大终端跳起来的时候,是时候站起来伸个懒腰了!

备注。- 1500秒 = 25分钟pomodoro - 240x80 = 终端大小,240个字符行,80行。对我来说,填满一个屏幕很明显。

信用: http://www.linuxquestions.org/questions/linux-newbie-8/countdown-timer-for-linux-949463/

0
0
0
2016-04-20 15:14:05 +0000

这和公认的答案类似,但是 terdon 的 countdown()给我带来了语法错误。不过这个对我来说很好用:

function timer() { case "$1" in -s) shift;; *) set $(($1 * 60));; esac; local S=" "; for i in $(seq "$1" -1 1); do echo -ne "$S\r $i\r"; sleep 1; done; echo -e "$S\rTime's up!"; }

你可以把它放在.bashrc里,然后用: timer t (其中t是时间,以分钟为单位)。

-2
-2
-2
2014-08-18 17:19:37 +0000

如果你出于任何原因想要一个可编译的程序,下面的方法就可以了。

#include <iostream>
#include <string>
#include <chrono>

int timer(seconds count) {
  auto t1 = high_resolution_clock::now();
  auto t2 = t1+count;
  while ( t2 > high_resolution_clock::now()) {
    std::cout << "Seconds Left:" <<
    std::endl <<
      duration_cast<duration<double>>(count-(high_resolution_clock::now()-t1)).count() << 
    std::endl << "0x1&33[2A0x1&33[K";
    std::this_thread::sleep_for(milliseconds(100));
  }
  std::cout << "Finished" << std::endl;
  return 0;
}

这也可以用在其他程序中,而且很容易移植,如果bash环境不可用,或者你只是喜欢用编译过的程序 github