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

Is er een manier om een aftel- of stopwatch-timer in een terminal weer te geven?

Hoe kan ik een real-time countdown timer weergeven op de Linux terminal? Is er een bestaande app of, nog beter, een one liner om dit te doen?

答案 (22)

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

Ik weet niet waarom je beep nodig hebt, als je alleen een stopwatch wilt, kun je dit doen:

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

Dat laat je de seconden zien die in realtime verstrijken en je kunt het stoppen met Ctrl+C. Als je meer precisie nodig hebt, kun je dit gebruiken om je nanoseconden te geven:

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

Tenslotte, als je echt, echt “stopwatch formaat” wilt, waar alles begint bij 0 en begint te groeien, zou je iets als dit kunnen doen:

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

Voor een afteltimer (waar je oorspronkelijke vraag niet om vroeg) zou je dit kunnen doen (verander de seconden dienovereenkomstig):

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

Je kunt deze combineren tot eenvoudige commando’s door bash (of welke shell je ook verkiest) functies te gebruiken. Voeg in bash deze regels toe aan je ~/.bashrc (de sleep 0.1 zorgt ervoor dat het systeem 1/10e seconde wacht tussen elke run, zodat je je CPU niet overbelast):

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
}

Je kunt dan een afteltimer van een minuut starten door te draaien:

countdown 60

Je kunt twee uur aftellen met:

countdown $((2*60*60))

of een hele dag met:

countdown $((24*60*60))

En de stopwatch starten met:

stopwatch
  • *

Als je zowel met dagen als met uren, minuten en seconden moet kunnen omgaan, zou je iets als dit kunnen doen:

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
}

Noteer dat de stopwatch functie niet getest is voor dagen omdat ik er niet echt 24 uur op wilde wachten. Het zou moeten werken, maar laat het me alsjeblieft weten als het niet werkt.

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

Mijn favoriete manier is:

Start:

time cat

Stop:

ctrl+c
  • *

Zoals @wjandrea hieronder opmerkte, is een andere versie om te starten:

time read

en druk op Enter om te stoppen

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

Ik was op zoek naar hetzelfde en heb uiteindelijk iets uitgebreiders in Python geschreven:

Dit zal je een eenvoudige 10-seconden aftelling geven:

sudo pip install termdown
termdown 10

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

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

stel een timer in voor 15 minuten

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

edit: Ik had een heleboel links open staan, en ik dacht dat dit specifiek voor osx was, sorry daarvoor. Ik laat mijn antwoord achter zodat anderen op de hoogte zijn van het verlof op de BSDs.

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

Ik heb deze gebruikt:

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
)

Voorbeeld:

countdown "00:07:55"

Hier is een bron .

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

Dit is voor een stopwatch met honderdsten van seconden:

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

Voorbeeld

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

Kort antwoord:

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

Uitleg:

Ik weet dat er veel antwoorden zijn, maar ik wil gewoon iets posten dat heel dicht bij de vraag van OP ligt, dat ik persoonlijk zou accepteren als inderdaad “ oneliner countdown in terminal”. Mijn doelen waren:

  1. One liner.
  2. Aftellen.
  3. Gemakkelijk te onthouden en in console te typen (geen functies en zware logica, alleen bash).
  4. Vereist geen extra software om te installeren (kan op elke server gebruikt worden waar ik via ssh heen ga, zelfs als ik daar geen root heb).

Hoe het werkt:

  1. seq drukt getallen af van 60 tot 1.
  2. echo -ne "\r$i " brengt de caret terug naar het begin van de string en drukt de huidige $i waarde af. Een spatie erna is nodig om de vorige waarde te overschrijven, als die langer was met tekens dan de huidige $i (10 - 9).
4
4
4
2015-02-01 14:42:54 +0000

Ik heb het zeer goede antwoord van terdon gecombineerd, in functie die tegelijkertijd de tijd sinds begin en tijd tot einde weergeeft. Er zijn ook drie varianten, zodat het gemakkelijker aan te roepen is (je hoeft geen bash wiskunde te doen), en het is ook geabstraheerd. Gebruiksvoorbeeld :

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

En zoiets als werk timer:

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

En als je een hele specifieke tijd nodig hebt:

{ ~ } » 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 is de code om in je . 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]})) 
}

Combineer dit met een manier om geluid af te spelen in linux terminal speel mp3 of wav bestand af via Linux command line ) of cygwin (cat /path/foo.wav > /dev/dsp werkt voor mij in babun/win7) en je hebt een simpele flexibele timer met alarm!

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

Ik eindigde met het schrijven van mijn eigen shell script: (https://gist.github.com/tir38/5855000)

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

Het verbaast me dat niemand de sleepenh tool heeft gebruikt in hun scripts. In plaats daarvan gebruiken de voorgestelde oplossingen ofwel een sleep 1 tussen opeenvolgende timer outputs ofwel een busy loop die zo snel mogelijk output. De eerste is ontoereikend omdat door de kleine tijd die het afdrukken in beslag neemt, de uitvoer in werkelijkheid niet eenmaal per seconde zal gebeuren maar iets minder dan dat, wat suboptimaal is. Als er genoeg tijd verstreken is, zal de teller een seconde overslaan. Dit laatste is onvoldoende omdat het de CPU zonder goede reden bezig houdt.

De tool die ik in mijn $PATH heb ziet er als volgt uit:

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

Het script kan worden gebruikt als een stopwatch (aftellend tot het wordt onderbroken) of als een timer die gedurende de opgegeven tijd loopt. Aangezien het commando sleep wordt gebruikt, kan met dit script de tijdsduur worden opgegeven waarvoor geteld moet worden, met dezelfde precisie als uw sleep toestaat. Op Debian en afgeleiden omvat dit slaapstanden van subseconden en een mooie menselijk leesbare manier om de tijd op te geven. Dus je kunt bijvoorbeeld zeggen:

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

En zoals je kunt zien, liep het commando precies gedurende 2 minuten en 4,6 seconden, zonder veel magie in het script zelf.

EDIT :

Het sleepenh gereedschap komt uit het gelijknamige pakket in Debian en zijn afgeleiden zoals Ubuntu. Voor distributies die het niet hebben, komt het uit https://github.com/nsc-deb/sleepenh

Het voordeel van sleepenh is, dat het in staat is om rekening te houden met de kleine vertraging die zich in de loop van de tijd ophoopt door het verwerken van andere dingen dan de slaap tijdens een loop. Zelfs als men gewoon 10 keer sleep 1 in een lus zou doen, zou de totale uitvoering iets meer dan 10 seconden duren vanwege de kleine overhead die komt van het uitvoeren van sleep en het itereren van de lus. Deze fout stapelt zich langzaam op en zou na verloop van tijd onze stopwatch timer steeds onnauwkeuriger maken. Om dit probleem op te lossen, moet je bij elke iteratie van de lus de precieze tijd om te slapen berekenen, die gewoonlijk iets minder dan een seconde is (voor intervaltimers van een seconde). Het gereedschap sleepenh doet dit voor je.

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

Een andere aanpak

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

Voor Mac:

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

Als men een signaal wil als het op nul komt, zou men het bijvoorbeeld kunnen bouwen met een commando dat een niet-nul exit-status teruggeeft bij nul en het combineren met watch -b, of zoiets, maar als men een meer uitgebreid script wil bouwen, is dit waarschijnlijk niet de manier om te gaan; het is meer een “quick and dirty one-liner” type oplossing.

  • *

Ik vind het watch programma in het algemeen leuk. Ik zag het voor het eerst nadat ik al ontelbare while sleep 5; do loops had geschreven voor verschillende effecten. watch was aantoonbaar mooier.

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

is een eenvoudige stopwatch die eeuwig loopt.

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

Installeren

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

Gebruik

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

Doe alsof je een persoon bent op OSX die op zoek is naar een command line stopwatch. Stel dat je de gnu tools niet wilt installeren en gewoon met de unix date

wilt werken, doe in dat geval wat @terdon zegt maar met deze wijziging:

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

Kijk eens naar TermTime , het is een mooie terminal-gebaseerde klok en stopwatch:

pip install termtime

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

Gebruik gewoon horloge + datum in UTC-tijd. Je kunt ook een of ander pakket installeren voor een groot scherm…

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'

Probeer het!

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

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

Voor toekomstige referentie, er is een command line tool genaamd µTimer met zeer eenvoudige command line opties voor een countdown/count-up timer.

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

Een python voorbeeld:

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

Een GUI-versie van de stopwatch

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

Ik vond deze vraag eerder vandaag, toen ik op zoek was naar een term applicatie om een grote aftelklok weer te geven voor een workshop. Geen van de suggesties was precies wat ik nodig had, dus heb ik snel een andere in elkaar gezet in Go: https://github.com/bnaucler/cdown

Aangezien de vraag al voldoende beantwoord is, beschouw dit als voor het nageslacht.

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

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

Als die grote terminal met gele tekst opspringt, tijd om op te staan en je uit te rekken!

Opmerkingen: - 1500 seconden = 25 minuten pomodoro - 240x80 = terminal grootte met 240 karakter rij, en 80 rijen. Vult een scherm voor mij merkbaar op.

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

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

Dit is vergelijkbaar met het geaccepteerde antwoord, maar terdon’s countdown() gaf me syntaxisfouten. Deze werkt echter geweldig voor mij:

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!"; }

Je kunt het in .bashrc stoppen en dan uitvoeren met: timer t (waarbij t de tijd in minuten is).

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

Als je om wat voor reden dan ook een compileerbaar programma wilt, zou het volgende kunnen werken:

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

Dit kan ook in andere programma’s gebruikt worden en gemakkelijk geport worden, als een bash omgeving niet beschikbaar is of als je gewoon liever een gecompileerd programma gebruikt github