Как использовать таймер в Bash?

30

Мне нужен был таймер, который запускается в самом начале сценария и останавливается в конце.

Mindfreak
источник
2
пожалуйста, напишите цель, которую вы хотите достичь. для измерения рабочего времени скрипта используйте timeкоманду (time ./script.sh), для распечатки текущего времени используйте dateкоманду и так далее.
Раш
stackoverflow.com/questions/3840558/…
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件
Использовать базовый linux cmd:, time yourprogram.shкоторый объяснил @Marius Cotofana
Мартейн ван Везел

Ответы:

29

Если вы хотите продолжительность в секундах, в верхней части использования

start=$SECONDS

и в конце

duration=$(( SECONDS - start ))
Гленн Джекман
источник
Что если это займет больше секунд?
Питикос
@Pithikos Смотрите ответ Филиппа Гиббона ниже
xhienne
23

Вы можете использовать встроенную timeкоманду Linux . Со страницы руководства:

КОМАНДА времени [аргументы]

время определяет, какую информацию отображать о ресурсах, используемых КОМАНДОЙ, из строки FORMAT. Если в командной строке не указан формат, но задана переменная среды TIME, в качестве формата используется ее значение.

Чтобы рассчитать время cleanup.shсценария, используйте:

$ time cleanup.sh
Мариус Котофана
источник
1
Знайте, что timeвы используете. hackernoon.com/…
km6zla
8

Я понимаю, что это довольно старый вопрос, но именно так я делаю это для всего, когда хочу / должен знать, сколько времени понадобилось, чтобы бежать.

Bash имеет встроенный таймер секунд в виде внутренней переменной с именем SECONDS( другие внутренние переменные см. Здесь )

Положите SECONDS=0перед тем, что вы проверяете время выполнения. Это должно быть после любого пользовательского ввода, чтобы получить хороший результат, поэтому, если вы запрашиваете информацию, ставьте ее после приглашения.

Затем поместите это в конец того, что вы проверяете:

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

Если вы хотите узнать только время в секундах, вы можете упростить приведенное выше:

echo "Completed in $SECONDS seconds"

В качестве примера:

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
Филип Гиббонс
источник
3
Ярлык для тех, кто не хочет такого сложного форматирования времени: date +%T -d "1/1 + $SECONDS sec"(ограничено менее чем 24
часами
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
источник
1
Привет, добро пожаловать на Unix SE! Ответы только для кода выглядят не очень хорошо, возможно, вы могли бы объяснить, что делает ваш скрипт.
Петер говорит восстановить Монику
0

@anask делает умное решение для этого ответа, просто я рекомендую использовать нативный $SECONDSвместо того, чтобы создать новый

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

Цель printfделения и деления состоит в том, чтобы преобразовать прошедшие секунды в соответствующие единичные часы, минуты, секунды соответственно.

Алекс Галиндо
источник