Antworten:
Ich bin mir nicht sicher, warum Sie das brauchen beep
. Wenn Sie nur eine Stoppuhr wollen, können Sie dies tun:
while true; do echo -ne "`date`\r"; done
Das zeigt Ihnen die Sekunden in Echtzeit und Sie können es mit Ctrl+ stoppen C. Wenn Sie eine höhere Genauigkeit benötigen, können Sie diese verwenden, um Nanosekunden zu erhalten:
while true; do echo -ne "`date +%H:%M:%S:%N`\r"; done
Wenn Sie wirklich, wirklich "Stoppuhr-Format" wollen, bei dem alles bei 0 beginnt und wächst, können Sie Folgendes tun:
date1=`date +%s`; while true; do
echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
done
Für einen Countdown-Timer (was nicht Ihre ursprüngliche Frage ist) können Sie dies tun (ändern Sie die Sekunden entsprechend):
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
Sie können diese zu einfachen Befehlen kombinieren, indem Sie bash-Funktionen (oder die von Ihnen bevorzugte Shell) verwenden. Fügen Sie in bash die folgenden Zeilen zu Ihrer hinzu ~/.bashrc
(dadurch sleep 0.1
wartet das System zwischen jedem Durchlauf eine Zehntelsekunde, damit Sie Ihre CPU nicht spammen):
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
}
Sie können dann einen Countdown-Timer von einer Minute starten, indem Sie Folgendes ausführen:
countdown 60
Sie können zwei Stunden zählen mit:
countdown $((2*60*60))
oder einen ganzen Tag mit:
countdown $((24*60*60))
Und starten Sie die Stoppuhr mit:
stopwatch
Wenn Sie in der Lage sein müssen, mit Tagen sowie Stunden, Minuten und Sekunden umzugehen, können Sie Folgendes tun:
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
}
Beachten Sie, dass die stopwatch
Funktion seit Tagen nicht mehr getestet wurde, da ich eigentlich nicht 24 Stunden darauf warten wollte. Es sollte funktionieren, aber bitte lassen Sie es mich wissen, wenn es nicht funktioniert.
bash
, kann ich damit leben (obwohl es ist höher als ich erwartet hatte , und ich habe auch den Schlaf zu meinem eigenen .bashrc hinzugefügt).
date +%s
- $ date1)) +% H:% M:% S) ";
echo -ne "$(date -ju -f %s $(($date1 -
Datum +% s )) +%H:%M:%S)\r"
;
play -q -n synth 2 pluck C5
.
Mein Lieblingsweg ist:
Anfang:
time cat
Halt:
ctrl+c
Wie @wjandrea unten kommentiert, ist eine andere Version auszuführen:
time read
und drücken Sie Enter
, um zu stoppen
time read
time read
schlägt in zsh fehl, time (read)
funktioniert aber .
Ich suchte das Gleiche und schrieb am Ende etwas ausführlicheres in Python:
Dies gibt Ihnen einen einfachen Countdown von 10 Sekunden:
sudo pip install termdown
termdown 10
Ich habe diesen benutzt:
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
)
Beispiel:
countdown "00:07:55"
Hier ist eine Quelle .
sh-3.2# man leave
Stellen Sie einen Timer für 15 Minuten ein
sh-3.2# leave +0015
Alarm set for Thu Nov 3 14:19:31 CDT 2016. (pid 94317)
sh-3.2#
edit: Ich hatte eine Reihe von Links offen, und ich dachte, dies sei spezifisch für osx, tut mir leid. Lassen Sie meine Antwort offen, damit andere wissen, dass sie in den BSDs Urlaub haben.
Dies ist für eine Stoppuhr mit Hundertstelsekunden:
#!/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
Ich habe die sehr gute Antwort von terdon in eine Funktion zusammengefasst, die gleichzeitig die Zeit seit dem Start und die Zeit bis zum Ende anzeigt. Es gibt auch drei Varianten, so dass es einfacher ist aufzurufen (Sie müssen keine Bash-Berechnungen durchführen) und es ist auch abstrahiert. Anwendungsbeispiel :
{ ~ } » 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
Und so etwas wie Arbeitstimer:
{ ~ } » 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
Und wenn Sie eine ganz bestimmte Zeit brauchen:
{ ~ } » 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
Hier ist der Code , der in Ihre .bashrc eingefügt werden soll
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]}))
}
Kombinieren Sie dies mit einem gewissen Art und Weise von Spielen Sound in Linux - Terminal ( Wiedergabe von MP3 oder WAV - Datei über Linux - Befehlszeile ) oder Cygwin ( cat /path/foo.wav > /dev/dsp
funktioniert für mich in Babun / win7) und Sie haben einen einfachen flexible Timer mit Alarm !
Ein anderer Ansatz
countdown=60 now=$(date +%s) watch -tpn1 echo '$((now-$(date +%s)+countdown))'
Für Mac:
countdown=60 now=$(date +%s) watch -tn1 echo '$((now-$(date +%s)+countdown))'
#no p option on mac for watch
Wenn man ein Signal haben möchte, wenn es Null erreicht, kann man es beispielsweise mit einem Befehl erstellen, der einen Exit-Status ungleich Null bei Null zurückgibt, und es mit watch -b
etwas anderem kombinieren , aber wenn man ein ausführlicheres Skript erstellen möchte, ist dies wahrscheinlich nicht der Weg zu gehen; Es handelt sich eher um eine "schnelle und schmutzige Einzeiler" -Lösung.
Ich mag das watch
Programm im Allgemeinen. Ich habe es zum ersten Mal gesehen, nachdem ich bereits unzählige while sleep 5; do
Loops mit unterschiedlichen Effekten geschrieben hatte. watch
war nachweislich schöner.
Am Ende habe ich mein eigenes Shell-Skript geschrieben: 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
Ich bin überrascht, dass niemand das sleepenh
Tool in seinen Skripten verwendet hat. Stattdessen verwenden die vorgeschlagenen Lösungen entweder eine sleep 1
zwischen aufeinanderfolgenden Zeitgeberausgaben oder eine Besetztschleife, die so schnell wie möglich ausgibt. Ersteres ist unzureichend, da aufgrund der geringen Zeit, die für das Drucken aufgewendet wird, die Ausgabe nicht einmal pro Sekunde erfolgt, sondern etwas weniger als die suboptimale. Wenn genügend Zeit verstrichen ist, überspringt der Zähler eine Sekunde. Letzteres ist unzureichend, da die CPU ohne triftigen Grund ausgelastet ist.
Das Tool, das ich in meinem habe, $PATH
sieht so aus:
#!/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
Das Skript kann entweder als Stoppuhr (bis zur Unterbrechung hochgezählt) oder als Timer verwendet werden, der für die angegebene Zeitdauer ausgeführt wird. Da der sleep
Befehl verwendet wird, können Sie mit diesem Skript die Dauer angeben, für die mit derselben Genauigkeit gezählt werden soll, wie Sie dies sleep
zulassen. Unter Debian und Derivaten umfasst dies einen Ruhezustand von weniger als einer Sekunde und eine gut lesbare Möglichkeit, die Zeit anzugeben. So kann man zum Beispiel sagen:
$ time countdown 2m 4.6s
countdown 2m 4.6s 0.00s user 0.00s system 0% cpu 2:04.60 total
Und wie Sie sehen, lief der Befehl genau 2 Minuten und 4,6 Sekunden, ohne viel Magie im Skript selbst.
EDIT :
Das sleepenh-Tool stammt aus dem gleichnamigen Paket in Debian und seinen Derivaten wie Ubuntu. Für Distributionen, die es nicht haben, stammt es von https://github.com/nsc-deb/sleepenh
Der Vorteil von sleepenh ist, dass es in der Lage ist, die geringe Verzögerung zu berücksichtigen, die sich im Laufe der Zeit aus der Verarbeitung anderer Dinge als dem Schlaf während einer Schleife ergibt. Selbst wenn man nur sleep 1
10 Mal in einer Schleife wäre, würde die Gesamtausführung etwas mehr als 10 Sekunden dauern, da die Ausführung sleep
und das Iterieren der Schleife einen geringen Mehraufwand verursachen . Dieser Fehler häufte sich langsam an und würde unsere Stoppuhr mit der Zeit immer ungenauer machen. Um dieses Problem zu beheben, muss für jede Schleifeniteration die genaue Ruhezeit berechnet werden, die normalerweise etwas kürzer als eine Sekunde ist (für Zeitintervalle von einer Sekunde). Das sleepenh-Tool erledigt dies für Sie.
sleep 0.1
. Was ist sleepnh
(ich kann es nicht in den Arch-Repos finden) und wie unterscheidet es sich von sleep
? Soweit ich das beurteilen kann, tun Sie im Grunde das Gleiche wie meine obige Antwort. Was vermisse ich?
sleep 5
ist, dass Sie genau 5 Sekunden lang nicht schlafen. Versuchen Sie es zum Beispiel time sleep 5
und Sie sehen, dass das Ausführen des Befehls etwas mehr als 5 Sekunden dauert. Im Laufe der Zeit häufen sich die Fehler. Mit dem Dienstprogramm sleepenh können Sie diese Häufung von Fehlern auf einfache Weise vermeiden.
sleepnh
besser ist als sleep
(Sie sagen nur, dass andere Antworten sleep 1
dies nicht tun) , nur das OP benutzt das) und ii), wo man es bekommt und wie man es installiert, da es kein Standardwerkzeug ist.
sleep
und sleepenh
im ersten Absatz erklärt. Jedenfalls war mir das wahrscheinlich nicht klar genug, so dass ich am Ende mehr darauf einging. Die Millisekunden-Genauigkeitsprobleme treten auf, wenn Sie sleep
einmal anrufen . Sie häufen sich mit der Zeit an und irgendwann ist dies bemerkbar. Ich habe nicht gesagt, dass andere nur verwenden sleep 1
. Ich sagte, dass sie sleep 1
oder eine Busyloop verwenden. Was sie immer noch tun. Zeigen Sie mir ein Gegenbeispiel. Die Antworten sleep 0.1
sind die gleichen wie die, mit der sleep 1
Ausnahme, dass sie Fehler noch schneller ansammeln.
Kurze Antwort:
for i in `seq 60 -1 1` ; do echo -ne "\r$i " ; sleep 1 ; done
Erläuterung:
Ich weiß, dass es viele Antworten gibt, aber ich möchte nur etwas sehr Nahes an der Frage von OP posten, die ich persönlich als " Oneliner Countdown im Terminal " akzeptieren würde . Meine Ziele waren:
Wie es funktioniert:
seq
druckt Zahlen von 60 bis 1.echo -ne "\r$i "
Bringt das Caret an den Anfang der Zeichenkette zurück und gibt den aktuellen $i
Wert aus. Leerzeichen nach dem Überschreiben des vorherigen Werts, wenn dieser länger als der aktuelle Wert war $i
(10 -> 9).Stellen Sie sich als OSX-Benutzer vor, der nach einer Stoppuhr für die Befehlszeile sucht. Stellen Sie sich vor, Sie möchten die Gnu-Tools nicht installieren und nur mit dem Unix laufendate
in diesem Fall mache wie @terdon sagt, aber mit dieser Modifikation:
function stopwatch(){
date1=`date +%s`;
while true; do
echo -ne "$(date -jf "%s" $((`date +%s` - $date1)) +%H:%M:%S)\r";
sleep 0.1
done
}
Verwenden Sie einfach watch + date in UTC-Zeit. Sie können auch ein Paket für große Displays installieren ...
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'
Versuch es!
Siehe auch http://www.cyberciti.biz/faq/create-large-colorful-text-banner-on-screen/
sw ist eine einfache Stoppuhr, die für immer läuft.
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
Ein Python-Beispiel:
#!/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()
Dies ist ähnlich wie die akzeptierte Antwort, aber Terdon countdown()
hat mir Syntaxfehler gegeben. Dieser funktioniert jedoch hervorragend für mich:
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!"; }
Sie können es .bashrc
eingeben und dann ausführen mit: timer t
(wobei t die Zeit in Minuten ist).
Ich habe diese Frage heute früher gefunden, als ich nach einer Semesteranwendung suchte, um einen großen Countdown-Timer für einen Workshop anzuzeigen. Keiner der Vorschläge war genau das, was ich brauchte, also habe ich schnell einen anderen in Go: https://github.com/bnaucler/cdown zusammengestellt
Da die Frage bereits ausreichend beantwortet ist, halten Sie dies für die Nachwelt.
$ sleep 1500 && xterm -fg gelb -g 240x80 &
Wenn das große Terminal mit dem gelben Text aufspringt, ist es Zeit aufzustehen und sich zu strecken!
Anmerkungen: - 1500 Sekunden = 25 Minuten Pomodoro - 240x80 = Terminalgröße mit 240 Zeichen und 80 Zeilen. Füllt einen Bildschirm für mich spürbar aus.
Bildnachweis: http://www.linuxquestions.org/questions/linux-newbie-8/countdown-timer-for-linux-949463/
Eine GUI-Version der Stoppuhr
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
Wenn Sie aus irgendeinem Grund ein kompilierbares Programm wünschen, funktioniert Folgendes:
#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;
}
Dies kann auch in anderen Programmen verwendet und einfach portiert werden, wenn keine Bash-Umgebung verfügbar ist oder Sie nur ein kompiliertes Programm bevorzugen
.zshrc
Rechten hinzugefügt, nachdem ich Ihre Antwort gelesen habe. Heute habe ichcountdown
das erste Mal benutzt und eine ziemlich hohe CPU-Auslastung festgestellt. Ich fügte einsleep 0.1
(ich weiß nicht, ob eine Ruhezeit von einem Bruchteil einer Sekunde auf allen Systemen unterstützt wird) hinzu, das das viel verbesserte. Der Nachteil ist natürlich eine weniger genaue Anzeigegenauigkeit, aber ich kann mit einer Abweichung von max. 100ms.