Я хотів би дізнатись, скільки часу триває операція в сценарії оболонки Linux. Як я можу це зробити?
Відповіді:
Використання команди time, як припускали інші, є гарною ідеєю.
Інший варіант - використовувати магічну вбудовану змінну $ SECONDS, яка містить кількість секунд з моменту запуску сценарію. Ви можете сказати:
START_TIME=$SECONDS
dosomething
ELAPSED_TIME=$(($SECONDS - $START_TIME))
Я думаю, що це особливо для bash, але оскільки ви працюєте на Linux, я припускаю, що ви використовуєте bash.
Використовуйте time
команду. time ls /bin
.
time
це не підходить , коли ви виконуєте складну послідовність команд
time (ls / ; sleep 2; ls /bin)
.
\
і ()
він став більш складним.
/usr/bin/time -f '%C => %E' (ls / ; sleep 2; ls /bin)
кидкиbash: syntax error near unexpected token '('
Спробуйте наступний приклад:
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
У багатьох відповідях згадується $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."
Ось сценарій, щоб знайти час, що минув у мілісекундах. Замініть рядок режиму сну 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
Просто, щоб допомогти таким, як я, які отримали повідомлення про помилку:
arithmetic expression: expecting primary: "-"
Перевірте свою оболонку, яка почнеться з:
#!/bin/bash
На здоров’я!
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
Вихід:
cmd sleep 1
time 1.00
cmd sleep 2
time 2.00
cmd sleep 3
time 3.00
Пояснення:
--output
: вивести час у файл.
За замовчуванням вихід виводиться на stderr, тому ця опція важлива для відокремлення часу від stderr команди.
--append
: додати до файлу замість перезапису.
Це дозволяє мені сконцентрувати весь вихідний показник тесту в одному файлі.
SECONDS
, він перестає мати свій спеціальний значення). Див. POSIX spec @ pubs.opengroup.org/onlinepubs/9699919799/basedefs/… , зарезервувавши малі регістри для використання додатків, маючи на увазі, що змінні оболонки та середовища мають єдиний простір імен - Зарезервовано простір імен змінних середовища, що містять малі літери для додатків.