Bash

Bash(Yad)使用浮點數而不是整數

  • June 13, 2018

我編寫了這個執行多個計時器的bash腳本。問題是我的數組儲存整數:

|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,000‌​000|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 使用整數(整數)?


解決方案

問題是 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"

那這個呢:

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

引用自:https://unix.stackexchange.com/questions/447533