linux shell 循环累加需在循环外初始化变量(如sum=0),用$((sum+=i))整数运算,避免管道导致子shell丢失变量值,并过滤非数字行。

在 Linux Shell 脚本中,循环内部累加统计数据,核心是用一个变量做“计数器”或“求和器”,每次循环更新它,并确保变量作用域正确(不被子 shell 隔离)。关键不在循环本身,而在变量的初始化、引用和算术运算方式。
初始化变量必须在循环外
Shell 中变量默认无类型,但数值运算需显式声明或用特定语法。常见错误是把 sum=0 写在 do 里面,导致每次循环都重置:
- ✅ 正确:循环前定义
sum=0,再进入for或while - ❌ 错误:
for i in ...; do sum=0; sum=$((sum + i)); done—— 每次都归零,最终只保留最后一次值
使用 $((...)) 进行整数累加
这是最常用、最可靠的方式,支持加减乘除和括号优先级:
-
sum=$((sum + i))或简写为((sum += i)) - 若从文件读取数字,先确保内容可转为整数,例如:
num=$(echo "$line" | tr -d '[:space:]') - 注意:不能写成
sum=$sum+$i,这会被当字符串拼接(如5+3),不会计算
处理非数字行要过滤
真实场景中,输入常含空行、标题、单位等。直接累加会报错或结果异常:
- 用正则判断是否为纯数字:
[[ "$line" =~ ^-?[0-9]+\.?[0-9]*$ ]] && sum=$((sum + line)) - 用
awk预处理更稳妥,比如:sum=$(awk '{s += $1} END {print s+0}' data.txt),避免 Shell 自己解析 - 若数据来自命令输出(如
ps aux的 RSS 列),建议用awk直接统计,比 Shell 循环更高效安全
while read 循环中保持变量值
用 cat file | while read line 时,管道会创建子 shell,循环内修改的变量在循环外不可见:
- ✅ 改用重定向:
while read line; do ((sum += line)); done - ✅ 或用进程替换:
while read line; do ((sum += line)); done - ❌ 避免:
cat data.txt | while read line; do ((sum += line)); done——sum在外部仍是初始值











