%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D1%82%20%D1%87%D0%B8%D1%81%D0%BB%D0%B0%20%D1%81%20%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%20%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9%20%D0%B2%D0%BC%D0%B5%D1%81%D1%82%D0%BE%20%D1%86%D0%B5%D0%BB%D1%8B%D1%85%20%D1%87%D0%B8%D1%81%D0%B5%D0%BB%20.png)
Я написал этот башсценарийкоторый запускает несколько таймеров. Проблема в том, что мой массив хранит целые числа:
|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1
Но другой пользователь LC_NUMERIC
настроен как it_IT.UTF-8
и его массив bash сильно отличается:
1,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|0,000000|1,000000
Это приводит к тому, что мой скрипт прерывается при проверке того, больше ли ноль элемента массива:
iActiveTimersCount=0
for ((i=0; i<MAX_TIMERS; i++)); do
if [[ ${aDuration[i]} -gt 0 ]] ; then
(( iActiveTimersCount++ ))
iAllTimersSaveSec=$(( iAllTimersSaveSec + ${aDuration[i]} ))
fi
done
Тесты командной строки
Эти тесты могут подтвердить, о чем «думает» bash:
$ if [[ 30,000000 -gt 0 ]]; then echo TRUE ; else echo FALSE ; fi
FALSE
$ if [[ 30.000000 -gt 0 ]]; then echo TRUE ; else echo FALSE ; fi
bash: [[: 30.000000: syntax error: invalid arithmetic operator (error token is ".000000")
FALSE
Дополнительная информация
Я пытался (через чат) заставить другого пользователя использовать export LC_ALL=C
и экспортировать LC_NUMERIC="en_US.UTF-8"
все это, но безрезультатно.
Как заставить bash использовать целые числа (integer)?
Решение
Проблема была в том, что YAD (Yet Another Dialog) хранил числа с десятичной точностью в Италии, но не в Северной Америке. Решением было использовать:
# When LC_NUMERIC=it_IT-UTF8 30 seconds can be `30,000000` or
# `30.000000` which breaks bash tests for `-gt 0`.
# Search and replace ".000000" or ",000000" to null
sed -i 's/[,.]000000//g' "$res1"
sed -i 's/[,.]000000//g' "$res2"
решение1
Как насчет этого:
iActiveTimersCount=0
for ((i=0; i<MAX_TIMERS; i++)); do
dur=$(awk -F, '{print $1}' <<<"${aDuration[i]}")
if [[ $dur -gt 0 ]] ; then
(( iActiveTimersCount++ ))
iAllTimersSaveSec=$(( iAllTimersSaveSec + dur ))
fi
done