Як виміряти тривалість у секундах у сценарії оболонки?


74

Я хотів би дізнатись, скільки часу триває операція в сценарії оболонки Linux. Як я можу це зробити?

Відповіді:


111

Використання команди time, як припускали інші, є гарною ідеєю.

Інший варіант - використовувати магічну вбудовану змінну $ SECONDS, яка містить кількість секунд з моменту запуску сценарію. Ви можете сказати:

START_TIME=$SECONDS
dosomething
ELAPSED_TIME=$(($SECONDS - $START_TIME))

Я думаю, що це особливо для bash, але оскільки ви працюєте на Linux, я припускаю, що ви використовуєте bash.


4
Єдиним застереженням, яке я тут додам, є те, що використання імен all-caps для власних змінних є поганою формою, оскільки це означає, що ви можете помилково перезаписати вбудовані в оболонку змінні (f / e, якщо хтось призначає SECONDS, він перестає мати свій спеціальний значення). Див. POSIX spec @ pubs.opengroup.org/onlinepubs/9699919799/basedefs/… , зарезервувавши малі регістри для використання додатків, маючи на увазі, що змінні оболонки та середовища мають єдиний простір імен - Зарезервовано простір імен змінних середовища, що містять малі літери для додатків.
Чарльз Даффі

40

Використовуйте timeкоманду. time ls /bin.


1
timeце не підходить , коли ви виконуєте складну послідовність команд
Shiplu Mokaddim

4
@ shiplu.mokadd.im Ні? Як щодо: time (ls / ; sleep 2; ls /bin).
Кіт

Якщо використовувати \ і ()він став більш складним.
Шиплу Мокаддім

3
@ shiplu.mokadd.im - чому не підходить? Поясніть. Мені здається чудовим / точним і використовую роками ...
bshea

1
@Keith У цього є деякі проблеми, такі як /usr/bin/time -f '%C => %E' (ls / ; sleep 2; ls /bin)кидкиbash: syntax error near unexpected token '('
Шиплу Мокаддім

35

Спробуйте наступний приклад:

START_TIME=$SECONDS
# do something
sleep 65

ELAPSED_TIME=$(($SECONDS - $START_TIME))

echo "$(($ELAPSED_TIME/60)) min $(($ELAPSED_TIME%60)) sec"    
#> 1 min 5 sec

9

У багатьох відповідях згадується $SECONDS, але ця змінна насправді навіть краща, ніж вони уявляють :

Присвоєння цій змінній скидає рахунок до присвоєного значення, а розширене значення стає призначеним значенням плюс кількість секунд з моменту призначення.

Це означає, що ви можете просто запитати цю змінну безпосередньо в кінці вашого сценарію, щоб надрукувати минулий час:

#!/usr/bin/env bash

# Do stuff...

echo "Script finished in $SECONDS seconds."

Ви також можете задати час меншим розділам, наприклад:

#!/usr/bin/env bash

# Do stuff

SECONDS=0

# Do timed stuff...

echo "Timed stuff finished in $SECONDS seconds."

5

Ось сценарій, щоб знайти час, що минув у мілісекундах. Замініть рядок режиму сну 60 кодом, який потрібно виконати.

a=0
while [ $a -lt 10 ]
do
    START_TIME=`echo $(($(date +%s%N)/1000000))`
    sleep 3
    END_TIME=`echo $(($(date +%s%N)/1000000))`
    ELAPSED_TIME=$(($END_TIME - $START_TIME))
    echo $ELAPSED_TIME
    if [ $a -eq 10 ]
    then
        break
    fi
    a=`expr $a + 1`
done

3

Просто, щоб допомогти таким, як я, які отримали повідомлення про помилку:

 arithmetic expression: expecting primary: "-"

Перевірте свою оболонку, яка почнеться з:

#!/bin/bash

На здоров’я!


1

GNU time

Мені також дуже подобається timeкоманда GNU : https://www.gnu.org/software/time/, яка пропонує деякі важливі варіанти порівняно зtime вбудованою Bash.

Зразок використання:

env time --format '%e' --output time.log sleep 1

Вихід:

1.00

Пояснення:

  • env: знайти /usr/bin/timeзамість вбудованого Bash

  • --format '%e': час друку в секундах, див man time .

    Часто цього я хочу під час порівняльного тестування: одне число, а не хвилини + секунди.

І важливою схемою, яку я часто використовую, є:

bench-cmd() (
  logfile=time.log
  echo "cmd $@" >> "$logfile"
  printf 'time ' >> "$logfile"
  bench_cmd="env time --append --format '%e' --output '$logfile' $@"
  eval "$bench_cmd"
  echo >> "$logfile"
)

rm -f time.log
bench-cmd sleep 1
bench-cmd sleep 2
bench-cmd sleep 3
cat time.log

GitHub вгору за течією .

Вихід:

cmd sleep 1
time 1.00

cmd sleep 2
time 2.00

cmd sleep 3
time 3.00

Пояснення:

  • --output: вивести час у файл.

    За замовчуванням вихід виводиться на stderr, тому ця опція важлива для відокремлення часу від stderr команди.

  • --append: додати до файлу замість перезапису.

    Це дозволяє мені сконцентрувати весь вихідний показник тесту в одному файлі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.