Jak korzystać z timera w bash?

30

Potrzebowałem licznika czasu, który rozpocznie się na samym początku skryptu, a zakończy na końcu.

MiNdFrEaK
źródło
2
napisz cel, który chcesz osiągnąć. do pomiaru timekomendy użycia czasu pracy skryptu (czas ./script.sh), do wydrukowania datekomendy użycia czasu pracy itd.
pędzi
stackoverflow.com/questions/3840558/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
Użyj podstawowego linux cmd time yourprogram.sh:, że @Marius Cotofana wyjaśnił
Martijn van Wezel

Odpowiedzi:

29

Jeśli chcesz czas trwania w sekundach, na najwyższym poziomie

start=$SECONDS

i na koniec

duration=$(( SECONDS - start ))
Glenn Jackman
źródło
Co jeśli zajmie to więcej niż sekundy?
Pithikos
@Pithikos Zobacz odpowiedź Philipa Gibbonsa poniżej
xhienne
23

Możesz użyć wbudowanego timepolecenia Linuksa . Ze strony podręcznika:

czas POLECENIE [argumenty]

czas określa, które informacje mają być wyświetlane o zasobach używanych przez polecenie, z ciągu FORMAT. Jeśli w wierszu komend nie podano żadnego formatu, ale ustawiona jest zmienna środowiskowa TIME, jej wartość jest używana jako format.

Aby zmierzyć czas cleanup.shskryptu, użyj:

$ time cleanup.sh
Marius Cotofana
źródło
1
Wiedz, timektórego używasz. hackernoon.com/…
km6zla,
8

Zdaję sobie sprawę, że jest to dość stare pytanie, ale w ten sposób robię to dla wszystkiego, kiedy chcę / muszę wiedzieć, ile czasu zajęło uruchomienie.

Bash ma wbudowany licznik sekund w postaci wewnętrznej zmiennej o nazwie SECONDS(patrz: tutaj dla innych zmiennych wewnętrznych)

Umieść SECONDS=0przed tym, co sprawdzasz, czas działania. Aby uzyskać dobry wynik, musi nastąpić po każdym wprowadzeniu przez użytkownika, więc jeśli monitujesz o informacje, umieść je po znaku zachęty.

Następnie umieść to na końcu tego, co sprawdzasz:

if (( $SECONDS > 3600 )) ; then
    let "hours=SECONDS/3600"
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $hours hour(s), $minutes minute(s) and $seconds second(s)" 
elif (( $SECONDS > 60 )) ; then
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $minutes minute(s) and $seconds second(s)"
else
    echo "Completed in $SECONDS seconds"
fi

Jeśli chcesz poznać czas w sekundach, możesz uprościć powyższe, aby:

echo "Completed in $SECONDS seconds"

Jako przykład:

read -rp "What's your name? " "name"
SECONDS=0
echo "Hello, $name"
if (( $SECONDS > 3600 )) ; then
    let "hours=SECONDS/3600"
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $hours hour(s), $minutes minute(s) and $seconds second(s)" 
elif (( $SECONDS > 60 )) ; then
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $minutes minute(s) and $seconds second(s)"
else
    echo "Completed in $SECONDS seconds"
fi
Philip Gibbons
źródło
3
Skrót dla tych, którzy nie chcą tak skomplikowanego formatowania czasu: date +%T -d "1/1 + $SECONDS sec"(ograniczony do mniej niż 24 godzin, ale możesz również dostosować, aby dodać dni)
xhienne
1
#!/bin/bash

start=$(date +%s)
#
# do something
sleep 10
#
#
end=$(date +%s)

seconds=$(echo "$end - $start" | bc)
echo $seconds' sec'

echo 'Formatted:'
awk -v t=$seconds 'BEGIN{t=int(t*1000); printf "%d:%02d:%02d\n", t/3600000, t/60000%60, t/1000%60}'
anask
źródło
1
Cześć, witamy na Unix SE! Odpowiedzi zawierające tylko kod nie wyglądają zbyt dobrze, być może możesz wyjaśnić, co robi twój skrypt.
peterh mówi o przywróceniu Moniki
0

@ anask zrobić sprytne rozwiązanie dla tej odpowiedzi, po prostu polecam użyć natywnego $SECONDSzamiast tego, aby utworzyć nowe

awk -v t=$SECONDS 'BEGIN{t=int(t*1000); printf "Elapsed Time (HH:MM:SS): %d:%02d:%02d\n", t/3600000, t/60000%60, t/1000%60}'

Celem podziału printfi podziału jest przeliczenie upływających sekund na odpowiadające im godziny, minuty, sekundy, odpowiednio.

Alex Galindo
źródło