У меня есть сценарий bash, который получает информацию о батарее.
Вот часть этого:
#!/bin/bash
if [ -f /sys/class/power_supply/BAT0/energy_full ]; then
EF=$( echo $(cat /sys/class/power_supply/BAT0/energy_full)/1000000|bc -l )
[ -n "$EF" ] && printf "energy_full: %0.2f Wh\n" $EF
fi
Этот скрипт работал долго, а потом внезапно перестал работать.
Например, переменная $EF
будет содержать 63.71100000000000000000, но вывод printf
представляет собой очень длинное число девять строк, которое начинается с -7309889081043958068.
Я пробовал использовать только %f, но безуспешно. Если я использую %d, он напечатает целое число до десятичной точки, но будет жаловаться на недопустимое число.
Я использую тестирование Debian.
GNU bash, версия 5.2.32(1)-выпуск (x86_64-pc-linux-gnu)
С набором -x
+ '[' -f /sys/class/power_supply/BAT0/energy_full ']'
++ bc -l
+++ cat /sys/class/power_supply/BAT0/energy_full
++ echo 63711000/1000000
+ EF=63.71100000000000000000
+ '[' -n 63.71100000000000000000 ']'
+ printf 'energy_full: %0.2f Wh\n' 63.71100000000000000000
energy_full: -nan Wh
Простое добавление printf 'energy_full: %0.2f Wh\n' 63.711
в скрипт приводит к той же ошибке.
Я использую локаль British UK. Раньше скрипт работал.
/bin/printf
работает, поэтому я могу использовать его как обходной путь. Вывод: energy_full: 63.71 Wh
Я не могу воспроизвести это с помощью bash 5.2.15(1). Какой вывод из cat /sys/class/power_supply/BAT0/energy_full
? Проверка -f
предполагает, что у вас может возникнуть состояние гонки, поэтому вместо этого выполните Energy_full=$(cat /sys/class/power_supply/BAT0/energy_full) и обработайте ошибку, проверив $?
Пожалуйста, сделайте минимально воспроизводимый пример. Я считаю, что это должно быть так же просто, как ef=63.711; printf "%0.2f\n" $ef
Какую локаль вы используете? Я использую французский язык, и мне пришлось заменить точку на запятую, чтобы все работало как положено. В противном случае я получил «строку 4: printf: 63.711: неверный номер» (переведено). Я использую Баш 5.0.
Практически никогда не бывает причин использовать $(echo $(command))
. Это то же самое, что просто написать $(command)
printf '%0.2f' 63.71100000000000000000
возвращает -нан? Оно отличается от первоначального значения, которое вы упомянули. А что, если вы просто используете 63 (с точки зрения @wjandrea)?
@Barmar Они перекачивают echo
в bc
. Тем не менее, я бы использовал следующую строку: bc -l <<< "$(cat ...)/1000000"
Это не отвечает на вопрос, но вы можете использовать bc для масштабирования числа вместо строки формата с помощью echo "energy_full: $(echo 'scale=2; 63711000/1000000' | bc -l)"
Пожалуйста, добавьте вывод locale
.
Это известная ошибка, патч доступен здесь mail.gnu.org/archive/html/bug-bash/2024-08/msg00027.html
/bin/printf, вероятно, лучший обходной путь.
Это известная ошибка. Патч доступен здесь: mail.gnu.org/archive/html/bug-bash/2024-08/msg00027.html
— comment by oguz ismail
Какая это версия Баша? Кроме того, добавьте команду
set -x
в начало скрипта, чтобы получить трассировку отладки, и посмотрите, что bash думает о команде, которую он выполняет.