Вопрос или проблема
Я пытаюсь отобразить, сколько времени требуется для выполнения моего скрипта в секундах и миллисекундах.
Вот мой код:
#!/bin/bash
before=10#`date +'%s%N'`
sleep 1
after=10#`date +'%s%N'`
echo "$before"
let "time_taken=$before-$after"
echo "$time_taken"
echo "$s"
Но я получаю следующую ошибку:
./tijdsmeting.sh: line 9: let: time_taken=10#1590683503N: value too great for base (error token is "10#15906835
~ |03N")
Я изучал это и обнаружил, что это связано с десятичными/восьмеричными/… Но я указал, что это должно быть десятичное, использовав #10
. Может быть, стоит использовать ibase
? И мой токен ошибки не 08
, как в других случаях в интернете..
%N
является расширением GNU-реализации date
(добавлено в 4.5.1 в 2002 году).
Теперь это также поддерживается
- date от ast-open с версии 2005-01-11
- busybox date с версии 1.17.0 (2010), хотя это там необязательно и обычно не включено по умолчанию
- toybox date с версии 0.7.4 (2017).
- FreeBSD date с 14.1 (2024)
Но, как правило, не другими реализациями.
Здесь, похоже, ваша date
не поддерживает %N
, и при выполнении date +%N
выдает N
(такое поведение я могу воспроизвести с FreeBSD до 14.1, и, вероятно, это то, что вы получите и в macos).
Так что:
let "time_taken=$before-$after"
(кстати, имелось в виду after-before) превращается во что-то вроде:
let 'time_taken=10#1590683503N-10#1590683504N'
И bash жалуется на это N
, которое не может быть использовано в базе 10.
В любом случае, выполнение date
само по себе займет тысячи наносекунд, так что такая точность, вероятно, не имеет смысла.
Здесь вы могли бы переключиться на zsh, где, как и в ksh93, специальная переменная $SECONDS
может быть представлена как число с плавающей запятой, и просто сделать:
#! /bin/zsh -
typeset -F SECONDS=0
sleep 1
time_taken=$SECONDS
Или использовать массивную переменную $epochtime
модуля zsh/datetime
, которая содержит секунды и наносекунды как 2 отдельных целых числа:
#! /bin/zsh -
zmodload zsh/datetime || exit
before=($epochtime)
sleep 1
after=($epochtime)
(( time_taken_ns = 1_000_000_000 * (after[1] - before[1]) + after[2] - before[2] ))
Ответ или решение
Ошибка "Value too great for base" в Bash скрипте: Решение и Объяснение
В вашем скрипте на Bash вы пытаетесь измерить время выполнения скрипта с использованием команды date
и выражения для вычисления разности времени. Однако, возникает ошибка value too great for base
, что связано с неверным синтаксисом в присвоении значений переменным before
и after
. Давайте рассмотрим ваш код и внесем необходимые изменения.
Код и Ошибка
Ваш текущий код выглядит так:
#!/bin/bash
before=10#`date +'%s%N'`
sleep 1
after=10#`date +'%s%N'`
echo "$before"
let "time_taken=$before-$after"
echo "$time_taken"
При выполнении этого кода вы получаете ошибку:
./tijdsmeting.sh: line 9: let: time_taken=10#1590683503N: value too great for base (error token is "10#15906835~ |03N")
Эта ошибка возникает из-за того, что при присвоении значений переменным before
и after
используется неверный синтаксис. Когда интерпретатор Bash пытается обработать выражение 10#1590683503N
, он не распознает N
как допустимый символ в десятичной системе счисления.
Решение
Чтобы устранить ошибку, вам необходимо исправить присвоение значений. Вот исправленный вариант вашего скрипта:
#!/bin/bash
# Получаем время в наносекундах
before=$(date +%s%N)
sleep 1
after=$(date +%s%N)
# Время выполнения в наносекундах
time_taken=$(( after - before ))
# Преобразуем в миллисекунды
time_taken_ms=$(( time_taken / 1000000 ))
# Печатаем результат
echo "Время выполнения: $time_taken наносекунд ($time_taken_ms миллисекунд)"
Объяснение Исправлений
-
Использование $(…) вместо 10#:
Изменениеbefore=10#...
наbefore=$(...)
позволяет корректно получить значение времени без ошибок интерпретации. -
Корректное вычисление времени выполнения:
Мы используем встроенные арифметические операции Bash для вычисления разностиafter - before
и храним результат вtime_taken
. -
Конвертация в миллисекунды:
Для удобства вы также можете дополнительно вывести время выполнения в миллисекундах, деля результат на 1,000,000.
Заключение
Ваш исправленный скрипт теперь корректно вычисляет время выполнения, не вызывая ошибок. Помните, что использование точного времени выполнения может иметь смысл в контексте ваших задач, но имейте в виду, что сам вызов date
может добавить некоторые накладные расходы, поэтому полученные значения могут варьироваться.
Если у вас возникнут дополнительные вопросы или вам нужна помощь в других аспектах скриптов на Bash, не стесняйтесь задавать. Успехов в программировании!