Shell脚本如何实现算术运算:从基础到进阶的完整指南
目录导读
- Shell算术运算概述
- 基础算术方法:expr与双括号
- let命令与$((...)) 高效写法
- 浮点数运算:bc与awk实战
- 变量自增自减与复合赋值
- 实际脚本案例:文件大小计算器
- 常见错误与调试技巧
- 问答环节:解决你的疑惑
Shell算术运算概述
Shell脚本中处理数值计算是自动化任务的核心能力,不同于高级语言,Shell的算术运算受限于其字符串解释特性——所有默认变量均为字符串,需通过特定语法触发数学计算,常见的算术场景包括:循环计数器、资源统计、时间差计算、日志阈值判定等。

需要注意的是,Bash默认仅支持整数运算(包括负数),浮点数需借助外部工具,本文将全面覆盖整数与浮点运算的多种实现方案,并给出SEO友好的实践建议。
基础算术方法:expr与双括号
1 使用expr命令
expr是最早的Shell算术命令,需用空格分隔操作符和操作数,且需转义乘号。
result=$(expr 5 + 3) # 加法 result=$(expr 10 - 4) # 减法 result=$(expr 6 \* 7) # 乘法(注意转义) result=$(expr 20 / 3) # 除法(只取整数部分)
缺点:语法繁琐,性能一般,且需谨慎处理空格。
2 双括号
这是现代Bash更推荐的整数运算语法,支持C语言风格操作符。
((sum = 100 + 200)) echo "Sum is $sum" # 或直接作为命令 if (( 10 > 5 )); then echo "true"; fi
优势:无需空格限制,支持逻辑判断,变量前可省略。
let命令与$((...)) 高效写法
1 let命令
let与双括号类似,但需避免在赋值中加空格。
let a=3+4 let b=a*2
在多数Bash版本中,let被替代更常见。
2 在赋值与字符串中嵌入
可用其获取计算结果并赋值给变量或嵌入字符串。
total=$(( 15 + 25 )) echo "Total: $((total + 10))" # 输出 Total: 50
这是最简洁的整数运算写法,推荐在单次计算中使用。
浮点数运算:bc与awk实战
1 使用bc(基本计算器)
bc支持任意精度浮点运算,通过管道传递表达式。
echo "scale=2; 10 / 3" | bc # 输出 3.33 result=$(echo "5.5 * 2.2" | bc)
选项:scale控制小数位数;-l加载标准数学库(三角函数等)。
2 使用awk
awk本身就是强语言,运算能力更丰富。
awk 'BEGIN {print 5.5 * 2.2}' # 输出 12.1
awk "BEGIN {print $a/$b}" # 使用shell变量
适合需要处理混合文本+计算的场景(如计算文件列和)。
变量自增自减与复合赋值
- 自增:
((i++))或let i++ - 自减:
((--j))或let j-- - 复合赋值:
((a += 5))、((b *= 3))
这些操作用于循环控制非常高效。
counter=0 for file in *.txt; do ((counter++)) done echo "处理了 $counter 个文件"
实际脚本案例:文件大小计算器
需求:计算指定目录下所有.log文件的总大小(单位MB),保留两位小数。
#!/bin/bash total=0 for f in /var/log/*.log; do size=$(stat -c%s "$f") # 获取字节数 total=$((total + size)) done echo "scale=2; $total / 1048576" | bc # 转换为MB
要点:先整数累加避免浮点精度问题,最后统一转换。
常见错误与调试技巧
| 错误 | 原因 | 修正 |
|---|---|---|
expr 5+3 报错 |
缺少空格 | expr 5 + 3 |
1/3 输出0 |
整数除法截断 | 用 echo "scale=3; 1/3" \| bc |
a=$a+1 得到字符串 |
未触发算术运算 | 改为 a=$((a+1)) 或 ((a++)) |
let a = 5 报错 |
let不允许赋值空格 |
let a=5 或 ((a=5)) |
调试技巧:用set -x开启执行跟踪,或echo打印中间变量类型。
问答环节:解决你的疑惑
Q1:为什么我用计算浮点数会报错?
A:Bash本身只支持整数,浮点必须用bc或awk。echo "10.5 + 3.2" | bc。
Q2:expr和哪个性能更好?
A:是Bash内建语法,不启动子进程,在循环中比expr快数倍,推荐全部用。
Q3:如何在算术表达式中引用变量且不混淆?
A:在内变量前可省略(但也可用),在bc字符串中用双引号包裹变量:echo "$var1 + $var2" | bc。
Q4:我需要计算一个科学计数法结果,Shell能处理吗?
A:Shell本身不能,但awk可以printf "%f\n"格式化输出,或者bc配合scale。echo "1e3 * 2" | bc。
Q5:如何检测一个字符串是否是纯数字,然后进行运算?
A:用正则[[ $var =~ ^[0-9]+$ ]]检测整数;浮点则用awk判断:awk 'BEGIN{exit(str ~ /^[0-9.]+$/)}'。
Q6:我写的算术运算在zsh中正常,在sh中报错,为什么?
A:Bash特性(如)在POSIX sh中不支持,脚本首行用#!/bin/bash替代#!/bin/sh。
Shell算术运算的核心在于区分整数与浮点场景,合理选择、expr、bc或awk,日常开发中优先使用处理循环和逻辑判断,涉及小数时果断引入bc,掌握这些技巧,能极大提升脚本的数值处理能力,从而在生产环境中高效完成日志分析、监控告警、数据转换等自动化任务。