Shell 預設僅處理字串,變數賦值 var=1+1 會直接存成字串「1+1」而非數值 2。若需進行數學運算,必須使用特定語法或外部工具。本文系統整理 Shell 中六種主流數學運算方法,涵蓋整數與浮點數運算、運算子支援度、語法細節與最佳實踐建議。
# 錯誤 1:直接賦值字串
var=1+1
echo $var # 輸出:1+1
# 錯誤 2:字串拼接
var=1
var=$var+1
echo $var # 輸出:1+1
let "運算式"
let 運算式1 運算式2 ...
+ - * / % ++ -- += -= *= /= %=、位元運算 & | ^ ~ << >>、邏輯運算 && || !、三元運算 ?:、逗號運算子**$(let "var+=1")&、;、())時需加雙引號let "a = 5 + 3"
let "b = a * 2"
let "c = 2 ** 10" # 1024
let "d = (a + b) * c" # 括號優先級正常運作
let "e++" # 遞增
let "f--" # 遞減
(( 運算式 ))
var=$(( 運算式 )) # 直接賦值結果
let 完全相同,但更直觀、可直接用於條件判斷if、while 中直接判斷真偽(非零為真)for 迴圈:for ((i=0; i<10; i++))(( var = 10 / 3 )) # var=3(整數除法)
(( var = 10 % 3 )) # var=1
(( var = 2 ** 8 )) # var=256
(( var += 5 )) # 累加
if (( var > 10 )); then echo "大於 10"; fi
# C 風格 for 迴圈
for ((i=1; i<=5; i++)); do echo $i; done
var=$[ 運算式 ]
$(( )) 類似,但變數引用必須加 $(var=$[$var+1])$(( )),$[] 保留相容性var=`expr 運算元1 運算子 運算元2 ...`
var=$(expr 運算元1 運算子 運算元2 ...)
expr $var + 1(非 expr $var+1)| & < <= = != >= > + - * / %\| \& \< \<= \>= \> \*\*:expr 5 \* 3var=10
var=$(expr $var + 5) # 15
var=$(expr $var \* 2) # 30
expr 10 \> 5 # 輸出 1(真)
expr "hello" : "he" # 字串匹配長度(2)
var=$(echo "運算式" | bc)
var=$(echo "scale=小數位數; 運算式" | bc)
% 外)scale=n 設定小數位數(預設 0,即整數)bc -l 載入 s()、c()、a()、l()、e()、j()bc 進入計算器# 基本浮點運算
var=3.14
var=$(echo "scale=2; $var * 3" | bc) # 9.42
# 進階:使用數學函數庫
var=$(echo "scale=4; s(3.14159/2)" | bc -l) # sin(π/2) ≈ 1
var=$(echo "scale=4; e(1)" | bc -l) # e ≈ 2.7183
# 互動模式範例
# bc
# scale=10
# 1/3
# .3333333333
# quit
var=$(echo "數值1 數值2" | awk '{printf "%g", $1 運算子 $2}')
log、sqrt、sin、cos、atan2、rand、srand、intprintf 格式控制輸出:%g(自動選擇 %e 或 %f)、%f(固定小數)、%.2f(兩位小數)# 基本四則運算
var=3.14
var=$(echo "$var 2" | awk '{printf "%g", $1 * $2}') # 6.28
# 使用數學函數
var=$(echo "$var 2" | awk '{printf "%.4f", sin($1/$2)}') # sin(1.57) ≈ 1.0000
# 批次處理:計算檔案第 3 欄總和
awk '{sum += $3} END {printf "%.2f\n", sum}' data.txt
| 方法 | 整數 | 浮點數 | 效能 | 適用場景 |
|---|---|---|---|---|
let | ✓ | ✗ | 極高(內建) | 腳本內簡單整數運算、遞增計數器 |
(( )) | ✓ | ✗ | 極高(內建) | 條件判斷、C 風格迴圈、複雜整數邏輯 |
$[] | ✓ | ✗ | 高(內建) | 舊版 Bash 相容性 |
expr | ✓ | ✗ | 低(外部) | POSIX 相容腳本、簡單整數運算 |
bc | ✓ | ✓ | 中(外部) | 高精度浮點、科學計算、財務金額 |
awk | ✓ | ✓ | 中(外部) | 欄位運算、管線串流、內建數學函數 |
(( )):語法清晰、效能最佳、支援完整 C 風格運算子bc:精度可控、標準計算器行為、支援數學函數庫awk:配合 printf 格式化輸出expr、bc、awk),改用內建 (( )) 累計,最後再管線給 bc/awk 處理浮點bc 指定 scale,避免浮點精度誤差Shell 數學運算方法多樣,關鍵在於區分整數與浮點數需求,並選擇效能與可讀性最佳的工具。日常腳本開發中,(( )) 處理整數邏輯、bc 處理精密浮點、awk 處理欄位運算,三者組合可覆蓋 99% 場景。掌握各方法語法細節(特別是 expr 空格與跳脫、bc 的 scale、awk 的 printf 格式),能避免 90% 的數值運算 Bug。