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

Gibt es eine Möglichkeit, einen Countdown- oder Stoppuhr-Timer in einem Terminal anzuzeigen?

Wie kann ich einen Echtzeit-Countdown-Timer auf dem Linux-Terminal anzeigen? Gibt es eine bestehende App oder, noch besser, einen One-Liner, um dies zu tun?

Antworten (22)

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

Ich bin mir nicht sicher, warum Sie beep benötigen, wenn Sie nur eine Stoppuhr wollen, können Sie dies tun:

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

Das zeigt Ihnen die vergehenden Sekunden in Echtzeit an und Sie können es mit Strg+C stoppen. Wenn Sie eine höhere Präzision benötigen, können Sie dies verwenden, um Nanosekunden zu erhalten:

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

Schließlich, wenn Sie wirklich, wirklich “Stoppuhr-Format” wollen, wo alles bei 0 beginnt und anfängt zu wachsen, könnten Sie so etwas 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 das ist, wonach Ihre ursprüngliche Frage fragte) könnten 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 in einfache Befehle kombinieren, indem Sie Funktionen der Bash (oder der von Ihnen bevorzugten Shell) verwenden. Fügen Sie in der Bash diese Zeilen zu Ihrem ~/.bashrc hinzu (das sleep 0.1 lässt das System zwischen jedem Durchlauf 1/10 Sekunde warten, damit Sie Ihre CPU nicht überlasten):

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 ausführen:

countdown 60

Sie können zwei Stunden herunterzählen mit:

countdown $((2*60*60))

oder einen ganzen Tag mit:

countdown $((24*60*60))

Und starten Sie die Stoppuhr mit:

stopwatch

Wenn Sie neben Stunden, Minuten und Sekunden auch mit Tagen umgehen können müssen, könnten Sie so etwas 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 Funktion stopwatch für Tage nicht getestet wurde, da ich nicht wirklich 24 Stunden darauf warten wollte. Es sollte funktionieren, aber bitte lassen Sie mich wissen, wenn es nicht funktioniert.

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

Mein Lieblingsweg ist:

Start:

time cat

Stopp:

ctrl+c

Wie @wjandrea unten kommentiert hat, ist eine andere Version zu starten:

time read

und zum Stoppen Enter drücken

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

Ich war auf der Suche nach der gleichen Sache und endete damit, etwas Aufwändigeres in Python zu schreiben:

So erhalten Sie einen einfachen 10-Sekunden-Countdown:

sudo pip install termdown
termdown 10

Quelle: https://github.com/trehn/termdown

14
14
14
2016-11-03 19:06:37 +0000
sh-3.2# man leave

einen Timer für 15 Minuten setzen

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

edit: Ich hatte einen Haufen Links geöffnet und dachte, das wäre spezifisch für OSX, tut mir leid. Ich lasse meine Antwort oben, damit andere wissen, dass es auf den BSDs geht.

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

Ich habe dieses verwendet:

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 .

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

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

Beispiel

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

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 posten, das der Frage von OP sehr nahe kommt und das ich persönlich auch als “Oneliner Countdown im Terminal” akzeptieren würde. Meine Ziele waren:

  1. One-Liner.
  2. Countdown.
  3. Leicht zu merken und in der Konsole einzugeben (keine Funktionen und schwere Logik, nur Bash).
  4. Benötigt keine zusätzlich zu installierende Software (kann auf jedem Server verwendet werden, auf den ich mich per ssh begebe, auch wenn ich dort nicht root habe).

Wie es funktioniert:

  1. seq druckt Zahlen von 60 bis 1.
  2. echo -ne "\r$i " setzt das Caret an den Anfang der Zeichenkette zurück und druckt den aktuellen $i-Wert. Das Leerzeichen danach wird benötigt, um den vorherigen Wert zu überschreiben, falls dieser um Zeichen länger war als das aktuelle $i (10 -> 9).
4
4
4
2015-02-01 14:42:54 +0000

Ich habe die sehr gute Antwort von Terdon zu einer Funktion zusammengefasst, die gleichzeitig die Zeit seit Start und die Zeit bis Ende anzeigt. Es gibt auch drei Varianten, so dass es einfacher aufzurufen ist (man muss nicht Bash-Math machen), 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 ein 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 benötigen:

{ ~ } » 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, den Sie in Ihre . 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]})) 
}

Kombinieren Sie dies mit einer Art Sound abspielen im Linux-Terminal mp3- oder wav-Datei über die Linux-Kommandozeile abspielen ) oder in cygwin (cat /path/foo.wav > /dev/dsp funktioniert bei mir in babun/win7) und Sie haben einen einfachen flexiblen Timer mit Alarm!

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

Ich habe schließlich 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
3
3
3
2016-11-24 15:38:57 +0000

Ich bin überrascht, dass niemand das Werkzeug sleepenh in seinen Skripten verwendet hat. Stattdessen verwenden die vorgeschlagenen Lösungen entweder ein sleep 1 zwischen aufeinanderfolgenden Timer-Ausgaben oder eine Busy-Schleife, die so schnell wie möglich ausgibt. Ersteres ist unzureichend, da die Ausgabe aufgrund der geringen Zeit, die für den Druck benötigt wird, nicht wirklich einmal pro Sekunde erfolgt, sondern etwas weniger, was suboptimal ist. Nachdem genug Zeit vergangen ist, wird der Zähler eine Sekunde überspringen. Letzteres ist unzureichend, weil es die CPU ohne guten Grund beschäftigt.

Das Tool, das ich in meinem $PATH habe, 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 verwendet werden (hochzählen, bis es unterbrochen wird) oder als Timer, der für die angegebene Zeit läuft. Da der Befehl sleep verwendet wird, kann in diesem Skript die Dauer, für die gezählt werden soll, mit der gleichen Genauigkeit angegeben werden, wie es Ihr sleep erlaubt. Unter Debian und Derivaten beinhaltet dies Sub-Sekunden-Schlafphasen und eine nette menschenlesbare Art, die Zeit anzugeben. So können Sie 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 können, lief der Befehl genau 2 Minuten und 4,6 Sekunden lang, ohne viel Magie im Skript selbst.

EDIT :

Das Werkzeug sleepenh stammt aus dem gleichnamigen Paket in Debian und seinen Derivaten wie Ubuntu. Für Distributionen, die es nicht haben, kommt es von https://github.com/nsc-deb/sleepenh

Der Vorteil von sleepenh ist, dass es in der Lage ist, die kleine Verzögerung zu berücksichtigen, die sich mit der Zeit durch die Verarbeitung anderer Dinge als den Schlaf während einer Schleife ansammelt. Selbst wenn man nur sleep 1 in einer Schleife 10 mal ausführen würde, würde die Gesamtausführung etwas mehr als 10 Sekunden dauern, wegen des kleinen Overheads, der durch die Ausführung von sleep und die Iteration der Schleife entsteht. Dieser Fehler sammelt sich langsam an und würde mit der Zeit unseren Stoppuhr-Timer immer ungenauer werden lassen. Um dieses Problem zu beheben, muss man bei jeder Schleifeniteration die genaue Zeit bis zum Einschlafen berechnen, die normalerweise etwas weniger als eine Sekunde beträgt (für Zeitgeber mit einem Intervall von einer Sekunde). Das Werkzeug sleepenh erledigt dies für Sie.

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

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 will, wenn es auf Null trifft, könnte man es z.B. mit einem Befehl bauen, der bei Null einen Exit-Status ungleich Null zurückgibt, und ihn mit watch -b oder so kombinieren, aber wenn man ein aufwändigeres Skript bauen will, ist das wahrscheinlich nicht der richtige Weg; es ist eher eine “schnelle und schmutzige Ein-Zeilen-Lösung”.


Ich mag das Programm watch im Allgemeinen. Ich sah es zum ersten Mal, nachdem ich bereits unzählige while sleep 5; do-Schleifen zu verschiedenen Effekten geschrieben hatte. watch war nachweislich schöner.

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

sw ist eine einfache Stoppuhr, die ewig läuft.

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

Installieren

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

Verwendung

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

Stellen Sie sich vor, Sie sind eine Person unter OSX, die nach einer Kommandozeilen-Stoppuhr sucht. Tun Sie so, als ob Sie die Gnu-Tools nicht installieren und nur mit dem Unix date

laufen wollen. In diesem Fall tun Sie, was @terdon sagt, aber mit dieser Änderung:

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

Schauen Sie sich TermTime an, es ist eine schöne terminalbasierte Uhr und Stoppuhr:

pip install termtime

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

Verwenden Sie einfach Uhr + Datum in UTC-Zeit. Sie können auch ein Paket für die große Anzeige 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'

Probieren Sie es aus!

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

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

Für die Zukunft gibt es ein Kommandozeilentool namens µTimer mit sehr einfachen Kommandozeilenoptionen für einen Countdown/Count-up-Timer.

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

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

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

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
0
0
0
2016-12-08 20:20:14 +0000

Habe diese Frage heute früh gefunden, als ich nach einer Term-Anwendung 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 zusammengestellt: https://github.com/bnaucler/cdown

Da die Frage bereits hinreichend beantwortet ist, betrachte ich dies der Nachwelt zuliebe.

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

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

Wenn das große Terminal mit dem gelben Text hochspringt, 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 merklich auf.

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

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

Dies ist ähnlich wie die akzeptierte Antwort, aber terdons countdown()gab mir Syntaxfehler. Das hier funktioniert für mich aber gut:

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 in .bashrc setzen und dann mit ausführen: timer t (wobei t die Zeit in Minuten ist).

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

Wenn Sie, aus welchen Gründen auch immer, ein kompilierbares Programm wünschen, würde das folgende funktionieren:

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

Dies kann auch in anderen Programmen verwendet und leicht portiert werden, wenn keine Bash-Umgebung verfügbar ist oder Sie einfach ein kompiliertes Programm bevorzugen github