Comment puis-je afficher un compte à rebours en temps réel sur le terminal Linux? Existe-t-il une application existante ou, mieux encore, une seule ligne pour le faire?
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 va vous montrer les secondes qui passent en temps réel et vous pouvez 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, "format chronomètre", où tout commence à 0 et commence à croître, vous pouvez faire quelque chose comme ceci:
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 vous demandait), vous pouvez le faire (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 les combiner en commandes simples en utilisant les fonctions bash (ou le shell de votre choix). Sous bash, ajoutez ces lignes à votre ~/.bashrc
(le sleep 0.1
fera attendre le système pendant 1/10ème 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 ensuite démarrer un compte à rebours d’une minute en exécutant:
countdown 60
Vous pouvez compter deux heures avec:
countdown $((2*60*60))
ou une journée entière en utilisant:
countdown $((24*60*60))
Et démarrez le chronomètre en lançant:
stopwatch
Si vous devez gérer des jours, des heures, des minutes et des secondes, vous pouvez procéder comme suit:
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. Cela devrait fonctionner, mais s'il vous plaît laissez-moi savoir si ce n'est pas le cas.
Ma manière préférée est:
Début:
time cat
Arrêtez:
ctrl+c
Comme @wjandrea a commenté ci-dessous, une autre version est à exécuter:
time read
et appuyez sur Enter
pour arrêter
Je cherchais la même chose et j'ai fini par écrire quelque chose de plus élaboré en Python:
Cela vous donnera un compte à rebours simple de 10 secondes:
Sudo pip install termdown
termdown 10
sh-3.2# man leave
régler une minuterie pour 15 minutes
sh-3.2# leave +0015
Alarm set for Thu Nov 3 14:19:31 CDT 2016. (pid 94317)
sh-3.2#
edit: J'avais un tas de liens ouverts, et je pensais que c'était spécifique à osx, désolé pour ça. Laissant ma réponse en suspens pour que les autres personnes soient au courant des congés accordés aux BSD.
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 un source .
Ceci est pour un chronomètre avec 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
}
}
J'ai combiné la réponse du très bon terdon à une fonction qui affiche en même temps le temps écoulé depuis le début et le temps jusqu'à la fin. Il existe également trois variantes, ce qui facilite l'appel (il n'est pas nécessaire de faire des calculs élémentaires), 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 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 de 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 un moyen de jouer du son dans un terminal linux ( lire 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 obtenez un simple minuterie flexible avec alarme !
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 on veut un signal quand il atteint zéro, on pourrait par exemple construisez-le avec une commande qui retourne à zéro un statut de sortie non nul et combinez-le avec watch -b
, ou quelque chose du genre, mais si vous voulez construire un script plus élaboré, ce n'est probablement pas la voie à suivre; il s’agit plus d’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.
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
Je suis surpris que personne n'ait utilisé l'outil sleepenh
dans leurs scripts. Au lieu de cela, les solutions proposées utilisent soit un sleep 1
entre les sorties de minuterie suivantes, soit une boucle occupée produisant le plus rapidement possible. La première solution est inadéquate car, en raison du peu de temps passé à l’impression, la sortie ne se produira pas une fois par seconde, mais un peu moins que ce qui est sous-optimal. Une fois le temps écoulé, le compteur passera une seconde. Ce dernier est inadéquat car il maintient le processeur occupé 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é comme chronomètre (en comptant jusqu'à l'interruption) ou comme une minuterie qui s'exécute pendant la durée spécifiée. Puisque la commande sleep
est utilisée, ce script permet de spécifier la durée à compter avec la même précision que votre sleep
permet. Sur Debian et ses dérivés, cela inclut les temps de sommeil inférieurs à une seconde et un moyen lisible pour l’utilisateur de Nice de spécifier l’heure. 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 constater, la commande a fonctionné exactement pendant 2 minutes et 4,6 secondes sans trop de magie dans le script lui-même.
EDIT:
L'outil sleepenh provient du paquet du même nom dans Debian et de ses dérivés, comme Ubuntu. Pour les distributions qui ne l’ont pas, cela vient de https://github.com/nsc-deb/sleepenh
L'avantage de sleepenh est qu'il est capable de prendre en compte le faible retard accumulé dans le temps par le traitement de choses autres que le sommeil pendant une boucle. Même si l'on multipliait simplement sleep 1
dans une boucle 10 fois, l'exécution globale prendrait un peu plus de 10 secondes en raison du petit temps système généré par l'exécution de sleep
et l'itération de la boucle. Cette erreur s'accumule lentement et rendrait, avec le temps, notre chronomètre de plus en plus imprécis. Pour résoudre ce problème, il est nécessaire que chaque itération de boucle calcule le temps de veille précis, qui est généralement légèrement inférieur à une seconde (pour les temporisateurs d’une seconde). L'outil sleepenh le fait pour vous.
Un exemple en 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()
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.
sw est un chronomètre simple qui fonctionnera pour toujours.
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
Imaginez que vous êtes une personne sur OSX à la recherche d'un chronomètre en ligne de commande. Imaginez que vous ne voulez pas installer les outils GNU et que vous voulez simplement vous lancer avec la variable unix date
dans ce cas, faites comme @terdon 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
}
Utilisez simplement watch + date en heure UTC. Vous pouvez également installer un paquet pour le grand affichage ...
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/
Ceci est similaire à la réponse acceptée, mais les erreurs de syntaxe countdown()
de terdon m'ont été envoyées. Celui-ci fonctionne bien pour moi, cependant:
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!"; }
Vous pouvez le mettre dans .bashrc
et ensuite l'exécuter avec: timer t
(où t est le temps en minutes).
Une version graphique 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
Vous avez trouvé cette question plus tôt dans la journée lorsque vous recherchez une application à terme pour afficher un compte à rebours important pour un atelier. Aucune des suggestions n’étant exactement ce dont j'avais besoin, j’en ai donc rapidement créé une autre dans Go: https://github.com/bnaucler/cdown
Comme la question a déjà reçu une réponse suffisante, considérez cela comme une question de postérité.
$ sleep 1500 && xterm -fg jaune -g 240x80 &
Quand ce gros terminal avec du texte jaune saute, il est temps de se lever et de s'étirer!
Remarques: - 1500 secondes = 25 minutes de pomodoro - 240x80 = taille du terminal avec 240 lignes de caractères et 80 lignes. Remplit un écran pour moi sensiblement.
Crédit: http://www.linuxquestions.org/questions/linux-newbie-8/countdown-timer-for-linux-949463/