Existe uma maneira de exibir um cronômetro de contagem regressiva ou cronômetro em um terminal?

134

Como posso exibir um cronômetro de contagem regressiva em tempo real no terminal do Linux? Existe um aplicativo existente ou, melhor ainda, um forro para fazer isso?

    
por tir38 24.06.2013 / 22:13

21 resposta

174

Não sei por que você precisa de beep , se tudo que você quer é um cronômetro, você pode fazer isso:

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

Isso mostrará os segundos passando em tempo real e você pode pará-lo com Ctrl + C . Se você precisar de maior precisão, poderá usar isso para fornecer nanossegundos:

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

Finalmente, se você realmente quer "formato de cronômetro", onde tudo começa em 0 e começa a crescer, você pode fazer algo assim:

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

Para um cronômetro de contagem regressiva (que não é o que sua pergunta original pediu), você poderia fazer isso (mudar segundos de acordo):

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

Você pode combiná-los em comandos simples usando as funções bash (ou qualquer que seja a sua preferência). No bash, adicione essas linhas ao seu ~/.bashrc (o sleep 0.1 fará o sistema esperar por 1/10 de segundo entre cada execução, para que você não envie spam à sua 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
}

Você pode então iniciar uma contagem regressiva de um minuto executando:

countdown 60

Você pode fazer uma contagem regressiva de duas horas com:

countdown $((2*60*60))

ou um dia inteiro usando:

countdown $((24*60*60))

Inicie o cronômetro executando:

stopwatch

Se você precisar lidar com dias, horas, minutos e segundos, faça algo assim:

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
}

Observe que a função stopwatch não foi testada há dias, pois eu realmente não queria esperar 24 horas por isso. Deve funcionar, mas por favor me avise se isso não acontecer.

    
por 25.06.2013 / 00:11
87

Minha maneira favorita é:

Iniciar:

time cat

Pare:

ctrl+c

Como @wjandrea comentou abaixo, outra versão deve ser executada:

time read

e pressione Enter para parar

    
por 30.03.2015 / 10:26
33

Eu estava procurando a mesma coisa e acabei escrevendo algo mais elaborado em Python:

Isso fornecerá uma contagem regressiva simples de 10 segundos:

sudo pip install termdown
termdown 10

Fonte: link

    
por 06.06.2014 / 09:06
13

Eu usei este aqui:

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
)

Exemplo:

 countdown "00:07:55"

Aqui está uma fonte .

    
por 26.06.2013 / 21:52
13
sh-3.2# man leave

defina um temporizador por 15 minutos

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

edit: Eu tinha vários links abertos, e achei que isso era específico para osx, desculpe por isso. Deixando minha resposta para que os outros saibam licença nos BSDs.

    
por 03.11.2016 / 20:06
6

Isto é para um cronômetro com centésimos de segundo:

#!/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
  }
}

Exemplo

    
por 29.12.2013 / 06:42
4

Combinei a resposta do muito bom perdão à função que, ao mesmo tempo, exibe o tempo desde o início e o tempo até o fim. Há também três variantes, por isso é mais fácil ligar (você não precisa fazer bash matemática) e também é abstraído. Exemplo de uso :

{ ~ }  » 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

E algo como temporizador de trabalho:

{ ~ }  » 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

E se você precisar de um tempo muito específico:

{ ~ }  » 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

Aqui está o código para colocar em seu .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]})) 
}

Combine isso com alguma forma de tocar som no terminal linux ( reproduz arquivos mp3 ou wav via linha de comando do Linux ) ou cygwin ( cat /path/foo.wav > /dev/dsp funciona para mim em babun / win7) e você tem um temporizador flexível simples com alarme !

    
por 01.02.2015 / 15:42
4

Outra abordagem

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

Para Mac:

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

Se alguém quiser um sinal quando chegar a zero, pode-se, por exemplo construí-lo com um comando que retornou um status de saída diferente de zero em zero e combiná-lo com watch -b , ou algo assim, mas se alguém quiser construir um script mais elaborado, provavelmente esse não é o caminho a seguir; é mais uma solução do tipo "quick and dirty one-liner".

Eu gosto do programa watch em geral. Eu vi pela primeira vez depois de já ter escrito incontáveis while sleep 5; do loops para efeitos diferentes. watch foi demonstravelmente melhor.

    
por 21.08.2014 / 21:13
3

Acabei escrevendo meu próprio script de shell: githubist

#!/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 
    
por 25.06.2013 / 02:40
3

Surpreende-me que ninguém tenha usado a ferramenta sleepenh em seus scripts. Em vez disso, as soluções propostas usam um sleep 1 entre as saídas subsequentes do temporizador ou um loop ocupado que gera o mais rápido possível. A primeira é inadequada porque, devido ao pequeno tempo gasto na impressão, a saída não acontecerá de fato uma vez por segundo, mas um pouco menos do que a que é sub-ótima. Depois de passar o tempo suficiente, o contador pulará um segundo. O último é inadequado porque mantém a CPU ocupada sem um bom motivo.

A ferramenta que tenho no meu $PATH tem esta aparência:

#!/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

O script pode ser usado como um cronômetro (contando até ser interrompido) ou como um cronômetro executado durante o período de tempo especificado. Como o comando sleep é usado, esse script permite especificar a duração para a qual contar na mesma precisão que o sleep permite. No Debian e nos derivados, isso inclui sub-segundos inativos e uma boa maneira legível de especificar a hora. Então, por exemplo, você pode dizer:

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

E como você pode ver, o comando funcionou exatamente por 2 minutos e 4,6 segundos sem muita mágica no próprio script.

EDITAR :

A ferramenta sleepenh vem do pacote com o mesmo nome no Debian e seus derivados como o Ubuntu. Para distribuições que não têm, ele vem do link

A vantagem do sleepenh é que ele é capaz de levar em conta o pequeno atraso que se acumula ao longo do tempo a partir do processamento de outras coisas além do sono durante um loop. Mesmo se apenas um sleep 1 em um loop 10 vezes, a execução global levaria um pouco mais de 10 segundos por causa da pequena sobrecarga que vem de executar sleep e iterar o loop. Esse erro se acumula lentamente e, com o tempo, tornaria o cronômetro do cronômetro cada vez mais impreciso. Para corrigir esse problema, é necessário que cada iteração de loop calcule o tempo preciso para o sono, que é geralmente um pouco menor que um segundo (para contadores de intervalo de um segundo). A ferramenta sleepenh faz isso por você.

    
por 24.11.2016 / 16:38
1

Para referência futura, existe uma ferramenta de linha de comando chamada µTimer com opções de linha de comando muito simples para um contador de contagem regressiva / contagem regressiva.

    
por 26.09.2014 / 17:21
1

Finja que você é uma pessoa no OSX em busca de um cronômetro de linha de comando. Faça de conta que você não quer instalar as ferramentas do GNU e só quer rodar com o unix date

nesse caso, faça como @terdon diz, mas com essa modificação:

function stopwatch(){
    date1='date +%s'; 
    while true; do 
        echo -ne "$(date -jf "%s" $(('date +%s' - $date1)) +%H:%M:%S)\r"; 
        sleep 0.1
    done
}
    
por 13.04.2015 / 14:34
1

Basta usar watch + date no horário UTC. Você também pode instalar algum pacote para exibição grande ...

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'

Experimente!

Veja também link

    
por 02.06.2015 / 03:12
1

sw é um cronômetro simples que será executado para sempre.

Instalar

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

Uso

sw-startastopwatchfrom0,savestarttimein~/.swsw[-r|--resume]-startastopwatchfromthelastsavedstarttime(orcurrenttimeifnolastsavedstarttimeexists)-"-r" stands for --resume
    
por 23.06.2017 / 23:06
1

Um exemplo de 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()

    
por 13.02.2014 / 13:00
0

Dê uma olhada no TermTime , é um relógio e um cronômetro com base no terminal:

pip install termtime

    
por 13.04.2019 / 16:58
0

Isso é semelhante à resposta aceita, mas countdown() de terdon me forneceu erros de sintaxe. Este aqui funciona muito bem para mim:

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!"; }

Você pode colocar em .bashrc e executar com: timer t (onde t é o tempo em minutos).

    
por 20.04.2016 / 17:14
0

Encontrei esta questão mais cedo hoje, ao procurar por um aplicativo de longo prazo para exibir um grande cronômetro de contagem regressiva para um workshop. Nenhuma das sugestões foi exatamente o que eu precisava, então rapidamente coloquei outra no Go: link

Como a pergunta já está suficientemente respondida, considere que isso seja para o bem da posteridade.

    
por 08.12.2016 / 21:20
0

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

Quando esse grande terminal com texto amarelo salta, é hora de se levantar e se esticar!

Notas:  - 1500 segundos = 25 minutos pomodoro  - 240x80 = tamanho do terminal com linha de 240 caracteres e 80 linhas. Preenche uma tela para mim visivelmente.

Crédito: link

    
por 25.01.2017 / 00:04
0

Uma versão GUI do cronômetro

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
    
por 05.11.2018 / 14:49
-2

Se você quiser um programa compilável por qualquer motivo, o seguinte funcionaria:

#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 << "3[2A3[K";
    std::this_thread::sleep_for(milliseconds(100));
  }
  std::cout << "Finished" << std::endl;
  return 0;
}

Isso também pode ser usado em outros programas e pode ser facilmente portado, se um ambiente bash não estiver disponível ou você simplesmente preferir usar um programa compilado

github

    
por 18.08.2014 / 19:19