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

Existe-t-il un moyen d'afficher un compte à rebours ou un chronomètre dans un terminal ?

Comment puis-je afficher un compte à rebours en temps réel sur le terminal Linux ? Existe-t-il une application existante ou, mieux encore, un seul paquebot pour le faire ?

Réponses (22)

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

Je ne sais pas pourquoi vous avez besoin de beep, si tout ce que vous voulez c'est un chronomètre, vous pouvez le faire :

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

Cela vous montrera les secondes qui passent en temps réel et vous pourrez l'arrêter avec Ctrl+C. Si vous avez besoin d'une plus grande précision, vous pouvez l'utiliser pour vous donner des nanosecondes :

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

Enfin, si vous voulez vraiment, vraiment le “format chronomètre”, où tout commence à 0 et commence à grandir, vous pouvez faire quelque chose comme ça :

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

Pour un compte à rebours (ce qui n'est pas ce que votre question initiale demandait), vous pourriez faire ceci (changer les secondes en conséquence) :

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
  • *

Vous pouvez combiner tout cela en commandes simples en utilisant les fonctions bash (ou n'importe quel shell que vous préférez). Dans bash, ajoutez ces lignes à votre ~/.bashrc (le sleep 0.1 fera attendre le système pendant 1/10e de seconde entre chaque exécution afin de ne pas spammer votre 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
}

Vous pouvez alors lancer un compte à rebours d'une minute en exécutant :

countdown 60

Vous pouvez faire un compte à rebours de deux heures avec :

countdown $((2*60*60))

ou une journée entière en utilisant

countdown $((24*60*60))

Et lancer le chronomètre en faisant :

stopwatch
  • *

Si vous devez être capable de gérer les jours aussi bien que les heures, les minutes et les secondes, vous pouvez faire quelque chose comme ça :

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
}

_Notez que la fonction stopwatch n'a pas été testée depuis des jours car je ne voulais pas vraiment attendre 24 heures. Elle devrait fonctionner, mais faites-moi savoir si ce n'est pas le cas.

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

Ma méthode préférée est la suivante :

Start :

time cat

Stop :

ctrl+c

Comme @wjandrea l'a commenté ci-dessous, une autre version est à exécuter :

time read

et appuyez sur Enter pour arrêter

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

Je cherchais la même chose et j'ai fini par écrire quelque chose de plus élaboré en Python :

Cela vous donnera un simple compte à rebours de 10 secondes :

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

régler un timer de 15 minutes

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

éditer : j'avais un tas de liens ouverts, et je pensais que c'était spécifique à osx, désolé pour ça. Je laisse ma réponse en haut pour que les autres soient au courant des congés sur les BSD.

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

J'ai utilisé celui-ci :

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
)

Exemple :

countdown "00:07:55"

Voici une source .

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

Ceci est pour un chronomètre avec des centièmes de seconde :

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

Exemple

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

Réponse courte :

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

Explication :

Je sais qu'il y a beaucoup de réponses, mais je veux juste poster quelque chose de très proche de la question d'OP, que personnellement j'accepterais comme étant en effet “un compte à rebours de colonel dans le terminal”. Mes objectifs étaient les suivants :

  1. Un paquebot.
  2. Compte à rebours.
  3. Facile à mémoriser et à taper dans la console (pas de fonctions et logique lourde, seulement des coups).
  4. Ne nécessite pas de logiciel supplémentaire à installer (peut être utilisé sur n'importe quel serveur sur lequel je vais via ssh, même si je n'y ai pas de racine).

Comment ça marche :

  1. seq imprime les numéros de 60 à 1.
  2. echo -ne "\r$i " renvoie le curseur au début de la chaîne et affiche la valeur actuelle de $i. Un espace après est nécessaire pour écraser la valeur précédente, si elle était plus longue en caractères que la valeur actuelle $i (10 -> 9).
4
4
4
2015-02-01 14:42:54 +0000

J'ai combiné la très bonne réponse du terdon, en une fonction qui affiche en même temps le temps depuis le début et le temps jusqu'à la fin. Il y a également trois variantes, ce qui rend l'appel plus facile (vous n'avez pas besoin de faire des maths de base), et il est également abstrait. Exemple d'utilisation :

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

Et quelque chose comme une minuterie de travail :

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

Et si vous avez besoin d'un temps très spécifique :

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

Voici le code à mettre dans votre . 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]})) 
}

Combinez cela avec une façon de jouer du son dans un terminal linux jouer un fichier mp3 ou wav via la ligne de commande Linux ) ou cygwin (cat /path/foo.wav > /dev/dsp fonctionne pour moi dans babun/win7) et vous avez un modèle simple et flexible avec alarme !

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

J'ai fini par écrire mon propre script 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

Je suis surpris que personne n'ait utilisé l'outil sleepenh dans ses scripts. Au lieu de cela, les solutions proposées utilisent soit un sleep 1 entre les sorties de timers ultérieures, soit une boucle occupée qui sort le plus vite possible. La première solution est inadéquate car, en raison du peu de temps passé à l'impression, la sortie ne se fera pas une fois par seconde mais un peu moins que ce qui est sous-optimal. Après un laps de temps suffisant, le compteur sautera une seconde. La seconde est inadéquate car elle occupe le processeur sans raison valable.

L'outil que j'ai dans mon $PATH ressemble à ceci :

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

Le script peut être utilisé soit comme un chronomètre (comptant jusqu'à l'interruption), soit comme un minuteur qui fonctionne pendant le temps spécifié. Puisque la commande sleep est utilisée, ce script permet de spécifier la durée pour laquelle il faut compter avec la même précision que celle de votre sleep. Sur Debian et ses dérivés, cela inclut des mises en sommeil de moins d'une seconde et une façon agréable et lisible par l'homme de spécifier le temps. Ainsi, par exemple, vous pouvez dire :

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

Et comme vous pouvez le voir, la commande a fonctionné exactement pendant 2 minutes et 4,6 secondes sans grande magie dans le script lui-même.

EDIT :

L'outil sleepenh vient du paquet du même nom dans Debian et ses dérivés comme Ubuntu. Pour les distributions qui ne l'ont pas, il vient de https://github.com/nsc-deb/sleepenh

L'avantage de sleepenh est qu'il est capable de prendre en compte le petit retard qui s'accumule au fil du temps du fait du traitement d'autres choses que le sommeil pendant une boucle. Même si l'on ne faisait que sleep 1 dans une boucle 10 fois, l'exécution globale prendrait un peu plus de 10 secondes en raison de la petite surcharge qui provient de l'exécution de sleep et de l'itération de la boucle. Cette erreur s'accumule lentement et, avec le temps, rendrait notre chronomètre de plus en plus imprécis. Pour résoudre ce problème, il faut que chaque itération de boucle calcule le temps précis de sommeil qui est généralement légèrement inférieur à une seconde (pour les chronomètres à intervalle d'une seconde). L'outil sleepenh fait cela pour vous.

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

Une autre approche

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

Pour Mac :

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

Si l'on veut un signal lorsqu'il atteint zéro, on peut par exemple le construire avec une commande qui renvoie un état de sortie non nul à zéro et le combiner avec watch -b, ou quelque chose comme ça, mais si l'on veut construire un script plus élaboré, ce n'est probablement pas la bonne solution ; c'est plutôt une solution de type “one-liner rapide et sale”.


J'aime le programme watch en général. Je l'ai vu pour la première fois après avoir déjà écrit d'innombrables boucles while sleep 5; do à différents effets. watch était manifestement plus agréable.

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

sw est un simple chronomètre qui fonctionnera pour toujours.

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

Imaginez que vous êtes une personne sur OSX à la recherche d'un chronomètre en ligne de commande. Prétendez que vous ne voulez pas installer les outils gnu et que vous voulez juste fonctionner avec l'unix date

dans ce cas faites comme @terdon le dit mais avec cette modification :

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

Regardez TermTime , c'est une belle horloge et un chronomètre à base de terminal :

pip install termtime

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

Il suffit d'utiliser la montre + la date en heure UTC. Vous pouvez également installer un paquet pour un affichage plus grand…

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'

Essayez-le !

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

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

Pour référence future, il existe un outil de ligne de commande appelé µTimer avec des options de ligne de commande très simples pour un compte à rebours/compte à rebours.

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

Un exemple 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()

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

Une version GUI du chronomètre

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

J'ai trouvé cette question plus tôt dans la journée, en cherchant une application de terme pour afficher un grand compte à rebours pour un atelier. Aucune des suggestions n'était exactement ce dont j'avais besoin, alors j'en ai rapidement rassemblé une autre dans Go : https://github.com/bnaucler/cdown

Comme la question a déjà reçu une réponse suffisante, considérez que c'est pour la postérité.

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

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

Quand le grand terminal avec le texte jaune saute, il est temps de se lever et de s'étirer !

Notes : - 1500 secondes = 25 minutes pomodoro - 240x80 = taille du terminal avec une ligne de 240 caractères, et 80 lignes. Remplit un écran pour moi de façon remarquable.

Crédit : http://www.linuxquestions.org/questions/linux-newbie-8/countdown-timer-for-linux-949463/

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

Cette réponse est similaire à la réponse acceptée, mais le 0x6 de Terdon& m'a valu des erreurs de syntaxe. Celle-ci fonctionne très bien pour moi, cependant :

countdown()

Vous pouvez la mettre dans 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!"; } et ensuite l'exécuter avec : .bashrc (où t est le temps en minutes).

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

Si vous souhaitez un programme compilable pour quelque raison que ce soit, voici ce qui pourrait fonctionner :

#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;
}

Cela peut être utilisé dans d'autres programmes également et facilement porté, si un environnement bash n'est pas disponible ou si vous préférez simplement utiliser un programme compilé github

Questions connexes

6
10
7
5
3