Réponses:
Je ne sais pas pourquoi vous avez besoin 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, "format chronomètre", où tout commence à 0 et commence à grandir, 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). Dans bash, ajoutez ces lignes à votre ~/.bashrc
( sleep 0.1
cela fera attendre le système pendant 1 / 10ème de seconde entre chaque exécution pour 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 être capable de gérer des jours ainsi que des heures, des minutes et des secondes, vous pouvez faire quelque chose comme ceci:
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 stopwatch
fonction n'a pas été testée depuis des jours car je ne voulais pas vraiment attendre 24 heures pour cela. Cela devrait fonctionner, mais s'il vous plaît, laissez-moi savoir si cela ne fonctionne pas.
bash
je fais cela dans , je peux vivre avec cela (même s'il est plus élevé que prévu et j'ai également ajouté le sommeil à mon propre fichier .bashrc).
date +%s
- $ date1)) +% H:% M:% S) ";
echo -ne "$(date -ju -f %s $(($date1 -
date +% s )) +%H:%M:%S)\r"
;
play -q -n synth 2 pluck C5
.
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
time read
time read
échoue dans zsh, mais time (read)
fonctionne.
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
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 .
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 des BSD.
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
}
}
return $1
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 résumé. 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 sur un terminal linux ( lire un fichier mp3 ou wav via une ligne de commande Linux ) ou cygwin ( cat /path/foo.wav > /dev/dsp
fonctionne pour moi dans babun / win7) et vous obtenez un simple timer 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 peut par exemple le construire avec une commande renvoyant un état de sortie non nul à zéro et le combiner avec watch -b
, ou quelque chose du genre, mais si on veut construire un script plus élaboré, c'est probablement pas le chemin à parcourir; il s’agit plus d’une solution de type "one-liner" rapide et sale.
J'aime le watch
programme en général. Je l'ai vu pour la première fois après avoir déjà écrit d'innombrables while sleep 5; do
boucles d'effets différents. 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' sleepenh
outil dans leurs scripts. Au lieu de cela, les solutions proposées utilisent soit un sleep 1
entre les sorties de temporisation 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 mes $PATH
looks 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 sleep
commande 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 des temps de sommeil inférieurs à une seconde et un moyen lisible pour l’heure 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 provient de https://github.com/nsc-deb/sleepenh
L'avantage de sleepenh est qu'il est capable de prendre en compte le petit retard accumulé dans le temps par le traitement de choses autres que le sommeil pendant une boucle. Même si on ne faisait que sleep 1
10 fois une boucle, l'exécution globale prendrait un peu plus de 10 secondes à cause du petit temps système généré par l'exécution 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.
sleep 0.1
. Qu'est-ce que c'est sleepnh
(je ne le trouve pas dans les dépôts Arch) et en quoi diffère-t-il sleep
? Autant que je sache, vous faites essentiellement la même chose que ma réponse ci-dessus. Qu'est-ce que je rate?
sleep 5
, c'est que vous ne dormez pas pendant exactement 5 secondes. Essayez par exemple time sleep 5
et vous verrez que l'exécution de la commande prend un peu plus de 5 secondes. Au fil du temps, les erreurs s'accumulent. L'utilitaire sleepenh permet d'éviter facilement cette accumulation d'erreur.
sleepnh
est meilleure que sleep
(vous ne dites d' autres réponses utilisent sleep 1
-qui ils ne le font pas , seul le PO l'utilise) et ii) où l'obtenir et comment l'installer car ce n'est pas un outil standard.
sleep
et sleepenh
dans le premier paragraphe. En tout cas, je n’étais probablement pas assez clair là-dessus, j’ai donc développé davantage à la fin. Les problèmes de précision en millisecondes sont ce que vous obtenez lorsque vous appelez sleep
une fois. Ils s'accumulent avec le temps et à un moment donné, c'est perceptible. Je n'ai pas dit que d'autres utilisent seulement sleep 1
. J'ai dit qu'ils utilisent sleep 1
ou un busyloop. Ce qu'ils font encore. Montrez-moi un contre exemple. Les réponses sleep 0.1
sont les mêmes que celles faites, sleep 1
sauf qu'elles accumulent les erreurs encore plus rapidement.
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 de OP, que personnellement, j'accepterais comme " compte à rebours oneliner dans le terminal ". Mes objectifs étaient:
Comment ça fonctionne:
seq
imprime les nombres de 60 à 1.echo -ne "\r$i "
renvoie le curseur au début de la chaîne et affiche la $i
valeur actuelle . Espace après qu'il soit nécessaire d'écraser la valeur précédente, si elle était plus longue de caractères que la valeur actuelle $i
(10 -> 9).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 utiliser unixdate
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 un 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/
sw est un simple chronomètre 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
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()
Ceci est similaire à la réponse acceptée, mais terdon countdown()
m'a donné des erreurs de syntaxe. 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
puis exécuter avec: timer t
(où t est le temps en minutes).
Vous avez trouvé cette question plus tôt dans la journée lorsque vous recherchez une application à terme pour afficher un compte à rebours volumineux pour un atelier. Aucune des suggestions ne correspondait exactement à ce dont j'avais besoin, aussi en ai-je 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, le temps de se lever et de s'étirer!
Remarques: - 1500 secondes = 25 minutes 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/
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
Si vous souhaitez un programme compilable pour quelque raison que ce soit, voici ce qui convient:
#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 << "\033[2A\033[K";
std::this_thread::sleep_for(milliseconds(100));
}
std::cout << "Finished" << std::endl;
return 0;
}
Cela peut également être utilisé dans d'autres programmes et facilement porté si un environnement bash n'est pas disponible ou si vous préférez simplement utiliser un programme compilé.
.zshrc
droite après avoir lu votre réponse. Aujourd’hui, j’ai utilisécountdown
la première fois et j’ai remarqué une utilisation assez élevée du processeur. J'ai ajouté unsleep 0.1
(je ne sais pas si un temps de repos d'une fraction de seconde est pris en charge sur tous les systèmes), ce qui l'a beaucoup amélioré. L’inconvénient est bien sûr une précision d’affichage moins précise, mais je peux vivre avec un écart de max. 100ms.