Shell 变量的数值计算实践详解
涵盖整数运算、小数计算、bc/awk 工具及九九乘法表实战,适合 Linux 运维与开发人员。
一、算术运算符概述
和其他编程语言类似,Shell 也支持丰富的算术运算符,用于执行数值计算和逻辑比较。
1.1 常用算术运算符
| 运算符 | 含义 | 示例 |
|---|---|---|
+ - | 一元正号/负号 | -5 |
+ - | 加 / 减 | 3 + 4 |
* / % | 乘 / 除 / 取模(取余) | 10 / 3,10 % 3 |
** | 幂运算 | 2 ** 3 = 8 |
++ -- | 自增 / 自减(前置/后置) | i++ 或 ++i |
! && ` | ` | |
< <= > >= | 比较运算符 | ((5 > 3)) |
== != = | 相等 / 不等 / 赋值 | ((a == b)) |
<< >> | 左移 / 右移位运算 | ((1 << 3)) = 8 |
& ` | ^` `~` | 按位与 / 或 / 异或 / 取反 |
= += -= *= /= %= | 赋值运算符 | ((a += 3)) 等价于 a = a + 3 |
1.2 Shell 中常用的算术运算命令
| 命令 | 说明 | 适用场景 |
|---|---|---|
$((...)) 或 ((...)) | 推荐,高效灵活,用于整数运算 | 日常脚本首选 |
let | 与 ((...)) 等价 | 老脚本中常见 |
expr | 整数运算,需注意空格和转义 | 较古老,不推荐新脚本 |
bc | Linux 计算器,支持整数 + 小数 | 需要小数运算时 |
awk | 文本处理工具,支持小数运算 | 配合文本处理或复杂表达式 |
$[...] | 旧语法,已被 $((...)) 取代 | 看懂即可,不推荐使用 |
declare -i | 声明整型变量 | 特殊场景 |
二、((...)) 双小括号 – 最推荐的整数运算方式
双小括号 ((...)) 是 Bash 内置的算术运算语法,效率高、写法简洁,是企业运维脚本中最常用的方式。
2.1 基本用法
| 用法 | 说明 |
|---|---|
((i = i + 1)) | 运算后赋值给变量 |
echo $((1 + 2)) | 用 $ 取值并输出 |
i=$((i + 1)) | 将运算结果赋值给变量 |
((8 > 7 && 5 == 5)) | 支持逻辑比较,用于条件判断 |
2.2 简单数值计算示例
bash
# 直接输出计算结果
echo $((1 + 1)) # 2
echo $((6 * 3)) # 18
# 给变量赋值
((i = 5))
((i = i * 2))
echo $i # 10
# 计算 1+2+...+100
a=$((100 * (100 + 1) / 2))
echo $a # 5050
2.3 复杂表达式
bash
((a = 1 + 2 * 3 - 4 % 3))
echo $a # 8
# 也可以在一行内完成赋值并取值
b=$((a = 1 + 2 * 3 - 4 % 3))
echo $b # 8
# 直接输出表达式的值
echo $((1 + 2 * 3 - 4 % 3)) # 8
优先级说明:
**(幂) >*/%>+-,与 C 语言一致。
2.4 比较与条件判断
((...)) 作为命令时,根据表达式的真假返回退出码:
- 表达式为真 → 返回
0(Shell 中的 true) - 表达式为假 → 返回
1(Shell 中的 false)
bash
# 3 < 8 成立,返回 0
((3 < 8))
echo $? # 0
# 3 > 8 不成立,返回 1
((3 > 8))
echo $? # 1
# 与 if 结合使用
if ((8 > 7 && 5 == 5)); then
echo yes # 输出 yes
fi
2.5 自增/自减运算符(前置与后置的区别)
基本概念
a++(后置自增):先返回变量当前值,再将变量 +1++a(前置自增):先将变量 +1,再返回新值a--和--a同理(自减)
实战演示
bash
a=10
# 后置自增:先返回 10,再让 a 变成 11
echo $((a++)) # 输出 10
echo $a # 输出 11
# 前置自减:先让 a-1 变成 10,再返回 10
echo $((--a)) # 输出 10
echo $a # 输出 10
性能提示(理解即可)
i++需要临时保存 i 的原值再返回,会开辟临时空间。++i直接在变量内存上操作并返回,性能略高(微秒级差异,普通脚本无需纠结)。
总结口诀
| 表达式 | 执行顺序 | 示例(a=10) |
|---|---|---|
echo $((a++)) | 先返回 a,后 a+1 | 输出 10,a 变成 11 |
echo $((a--)) | 先返回 a,后 a-1 | 输出 10,a 变成 9 |
echo $((++a)) | 先 a+1,再返回新值 | 输出 11,a 变成 11 |
echo $((--a)) | 先 a-1,再返回新值 | 输出 9,a 变成 9 |
2.6 ((...)) 与 $((...)) 的区别
| 用法 | 功能 | 示例 |
|---|---|---|
((表达式)) | 执行运算或比较,不输出结果,主要用于赋值或条件判断 | ((a = 5 + 3)) |
$((表达式)) | 返回表达式的值,用于输出或赋值给其他变量 | b=$((5 + 3)) |
bash
num=99
echo $((num + 1)) # 输出 100,num 不变
num=$((num + 1)) # num 变成 100
echo $num # 100
三、let 命令
let 的功能与 ((...)) 基本等价,写法略有不同,在老脚本中较常见。
bash
i=2
let i=i+8
echo $i # 10
# 等价于
((i = i + 8))
建议: 新脚本优先使用
((...)),写法更自然、更统一。
四、expr 命令(较古老,了解即可)
expr 是早期 Shell 中常用的整数运算工具,使用时必须注意运算符两侧有空格,乘号需要转义。
bash
expr 3 + 4 # 7
expr 3 \* 4 # 12(乘号必须转义)
expr 10 / 3 # 3(整数除法,截断小数)
expr 10 % 3 # 1
缺点:
- 只支持整数
- 运算符必须加空格,容易出错
- 乘号
*必须转义
建议: 新脚本中直接使用
((...))替代,无需再用expr。
五、bc 命令 – 支持小数运算的计算器
bc 是 Linux 下的高精度计算器,支持整数和小数运算,是 Shell 中处理浮点数的最佳工具。
5.1 基本语法
bash
echo "表达式" | bc
echo "scale=N; 表达式" | bc # scale 设置小数位数(仅对除法生效)
5.2 bc 常用运算符
| 符号 | 含义 |
|---|---|
+ - * / | 加减乘除 |
% | 取模(取余) |
^ | 幂运算 |
scale=N | 设置除法保留 N 位小数 |
5.3 实战示例
bash
# 整数运算
echo '1 + 3 * 4 - 6 / 3 * 3 % 4' | bc # 13
# 小数除法(不设置 scale 时,小数部分被截断)
echo '1/3' | bc # 0
# 设置 scale=4,保留 4 位小数
echo 'scale=4; 1/3' | bc # .3333
# 幂运算
echo '2^10' | bc # 1024
scale 的重要说明:
scale只对除法生效,不影响乘法、加减、幂运算。- 不设置
scale时,除法结果为整数(直接截断,不四舍五入)。
5.4 高级用法:生成并计算序列
计算 1+2+3+...+10 的值:
bash
seq -s + 10 | bc # 55
拆解:
seq 10→ 生成 1 2 3 … 10-s +→ 指定分隔符为+- 最终得到字符串
1+2+3+4+5+6+7+8+9+10,通过管道传给bc计算。
六、awk 命令 – 强大的文本与数值计算
awk 不仅可以处理文本,也能进行精确的小数运算,非常适合在命令行中快速计算。
bash
# 减法
echo 7.7 3.8 | awk '{print $1 - $2}' # 3.9
# 复杂表达式
echo 358 113 | awk '{print ($1 - 3) / $2}' # 3.14159
awk的数值计算能力很强,适合在文本处理流程中顺便完成运算。
七、$[...] – 过时的整数运算语法
bash
echo $[4 - 2] # 2
echo $[2 * 2] # 4
echo $[5 / 2] # 2(整数除法)
echo $[5 % 2] # 1
注意:
$[...]是旧版 Bash 兼容语法,在新脚本中应使用$((...))替代。只需看懂老脚本即可。
八、综合实战:九九乘法表(两种写法)
方式一:使用 $((...))
bash
#!/bin/bash
for ((i=1; i<=9; i++)); do
for ((j=1; j<=i; j++)); do
temp=$((i * j))
echo -n "$i*$j=$temp "
done
echo
done
方式二:使用 let
bash
#!/bin/bash
for ((i=1; i<=9; i++)); do
for ((j=1; j<=i; j++)); do
let "temp = i * j"
echo -n "$i*$j=$temp "
done
printf "\n"
done
运行效果(部分):
text
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
...
9*1=9 9*2=18 9*3=27 ... 9*9=81
九、各运算工具对比与选择建议
| 工具 | 支持小数 | 语法简洁度 | 推荐场景 |
|---|---|---|---|
$((...)) | ❌ | ⭐⭐⭐⭐⭐ | 日常整数运算(首选) |
let | ❌ | ⭐⭐⭐⭐ | 与 ((...)) 等价,老脚本中常见 |
expr | ❌ | ⭐⭐ | 了解即可,新脚本不建议使用 |
bc | ✅ | ⭐⭐⭐⭐ | 需要小数运算时 |
awk | ✅ | ⭐⭐⭐ | 文本处理中顺便计算 |
$[...] | ❌ | ⭐⭐⭐ | 过时语法,只需看懂 |
十、总结速记
- 整数运算优先用
$((...)):高效、简洁、兼容性好。 - 小数运算用
bc:echo "scale=2; 10/3" | bc ((...))做判断:真返回 0,假返回 1,与if配合完美。- 自增自减:
a++先返回后自增,++a先自增后返回。 - 九九乘法表:循环嵌套 +
$((i * j))或let,练手必备。

371

被折叠的 条评论
为什么被折叠?



