HOWTO · Linux
如何在 Bash 中进行递增/递减操作
在 Bash 中,可以使用 `+` 和 `-` 运算符或 `+=` 和 `-=` 运算符增减变量。也可以使用一元运算符 `++` 和 `--`,分别将整数加一或减一。
本页内容
递增和递减操作会让整数变量按固定数量变化。在 Bash 中,算术展开、算术命令、let、复合赋值和一元运算符都可以执行这些更新。选择一种能清楚表达变化量,也便于理解后续所用数值的写法。
使用 + 和 - 进行递增和递减
算术展开写作 $((...)),会生成一个可用于赋值或打印的值。算术命令 ((...)) 会计算表达式,也可以直接更新变量。内建命令 let 同样可以计算算术表达式;请给表达式加上引号,让 shell 将它作为一个参数传递。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
x=3
y=3
z=3
x=$((x + 1))
((y = y + 1))
let "z=z+1"
printf 'x: %s\ny: %s\nz: %s\n' "$x" "$y" "$z"
x=$((x - 1))
((y = y - 1))
let "z=z-1"
前三种更新分别用不同的算术写法加一,后三种则减一。需要表达式的值时,算术展开很有用;需要更新变量时,算术命令和 let 用起来更方便。示例输出中的 x:、y: 和 z: 标签保留为英文。Bash 算术使用整数值。
使用 += 和 -= 更新算术值
复合赋值 x+=amount 和 x-=amount 会将右侧的整数加到或减去左侧变量的值。它们分别等同于 x=x+amount 和 x=x-amount。当更新量大于一,或需要让更新量一目了然时,适合使用这两种写法。
本节中的代码以及显示的标签或输出仍为英文。
count=10
((count += 3))
printf 'after adding 3: %s\n' "$count"
((count -= 2))
printf 'after subtracting 2: %s\n' "$count"
这些表达式会直接修改 count。算术命令的状态取决于表达式的值是否为零,因此不要把该状态当作更新成功与否的指示。示例打印的英文标签是 after adding 3: 和 after subtracting 2:,保持原样。
使用 ++ 和 -- 每次改变一个单位
一元运算符 ++ 和 -- 分别加一和减一。作为独立的算术命令,((count++))、((++count))、((count--)) 和 ((--count)) 都会更新变量。
当表达式会使用运算符产生的值时,前缀和后缀的行为不同:++count 先更新,再产生新值;count++ 先产生旧值,再更新。-- 的顺序也相同。如果只关心变量更新后的值,请将更新单独写成一条语句,以免产生歧义。
本节中的代码以及显示的标签或输出仍为英文。
count=4
old=$((count++))
printf 'old: %s, count: %s\n' "$old" "$count"
new=$((++count))
printf 'new: %s, count: %s\n' "$new" "$count"
示例输出中的英文标签是 old:、count: 和 new:,保持原样。
在循环中使用递增和递减
循环条件决定循环何时结束,更新操作则让计数器逐步接近结束条件。两者要保持一致:计数器递增时,条件应设定上界;计数器递减时,条件应设定下界。
本节中的代码以及显示的标签或输出仍为英文。
for ((count = 1; count <= 3; count++)); do
printf '%s\n' "$count"
done
count=3
while ((count >= 1)); do
printf '%s\n' "$count"
((count--))
done
for 循环会在循环头中列出初始化、条件和递增操作。while 循环会先检查条件,并在循环体内执行递减。请确保每次更新最终都能让条件变为假。这两个循环示例打印的都是计数器数值,没有 x: 之类的标签。
Bash 算术的限制与常见问题
Bash 算术以整数为基础,不原生支持浮点计算。若要进行小数运算,请使用合适的外部计算器,或使用支持浮点数的语言,并将该工具视为单独的依赖项。
++ 和 += 1 都会让变量加一。一元形式简洁;复合赋值能明确指出变化量,也适用于更大的更新。只有在表达式的值会被使用时,前缀和后缀的区别才有影响,具体如上所述。
表达式的值为零时,算术命令返回状态 1;否则返回状态 0。对于 ((count--)),表达式使用递减前的值:将 count 从 1 减到 0 时返回状态 0;若从 0 开始,即使变量变为 -1,也会返回状态 1。对于 ((--count)) 和 ((count -= 1)),表达式使用递减后的值,因此将 1 减到 0 时会返回状态 1。当算术命令用作 if 或 while 条件,或在 set -e 下作为简单命令运行时,这一区别会影响控制流,因为非零状态可能改变程序的执行路径。在上面的递减循环中,((count--)) 将 1 减到 0 时返回状态 0;随后显式检查的 ((count >= 1)) 条件会结束循环。