返回

Shell脚本报错\

Linux

如何解决 Shell 脚本中的 "expr: non-integer argument" 错误

在编写 Shell 脚本过程中,你可能会遇到 "expr: non-integer argument" 这样的错误信息。这个错误通常在你尝试使用 expr 命令对非整数参数进行算术运算时出现。本文将深入分析这个错误的常见原因,并提供解决问题的实用方案,帮助你写出更健壮的 Shell 脚本。

expr 命令与非整数参数

expr 命令是 Shell 中进行算术运算的传统工具,但它对参数类型有着严格的要求。当你试图用 expr 处理包含空格或非数字字符的变量时,就会引发 "non-integer argument" 错误。

举个例子,假设你想计算变量 total 中所有数字的总和, total 的值是 "1 2 3",你可能会写出以下代码:

#!/bin/bash

total="1 2 3"
dollar=0

for a in $total; do
  dollar=`expr $dollar + $a`
done

echo "Total: $dollar"

这段代码看起来似乎没有问题,但当你运行它时,会抛出 "expr: non-integer argument" 错误。这是因为循环将 $total 中的 "1", "2", "3" 分别赋值给了 $a,而 expr 无法处理包含空格的字符串 "1 2 3"。

三种解决方案

为了解决这个问题,我们可以采用以下三种方法:

1. 利用数组存储数据

将需要求和的数字存储在数组中,然后遍历数组进行求和。

#!/bin/bash

total=(1 2 3)
dollar=0

for a in "${total[@]}"; do
  dollar=$((dollar + a))
done

echo "Total: $dollar"

在这个例子中,我们使用 () 将数字定义为数组 total,并使用 "${total[@]}" 在循环中遍历数组元素。$((...)) 是 Shell 内置的算术扩展,可以避免使用 expr 命令。

2. 使用 bc 命令进行计算

bc 命令是一个任意精度计算器,可以处理包含空格的数字字符串。

#!/bin/bash

total="1 2 3"
dollar=$(echo "$total" | bc)

echo "Total: $dollar"

这里我们使用 echo 命令将 $total 的值传递给 bc 命令,bc 会计算字符串中所有数字的总和并将结果存储在 dollar 变量中。

3. Shell 内置算术扩展

现代 Shell 环境支持使用 $((...)) 进行算术扩展,这种方法更加简洁高效。

#!/bin/bash

total="1 2 3"
dollar=0

for a in $total; do
  dollar=$((dollar + $a))
done

echo "Total: $dollar"

在这个例子中,我们直接使用 $((...))dollar + $a 的计算结果赋值给 dollar,避免了使用 expr 命令和额外的管道操作。

总结

"expr: non-integer argument" 错误是 Shell 脚本编写过程中常见的错误之一,通过理解错误的根源以及掌握不同的解决方案,你可以轻松解决这类问题。选择适合你的方法,并将其应用到你的 Shell 脚本中,写出更加健壮和高效的代码。

常见问题解答

  1. 为什么 expr 命令无法处理包含空格的数字字符串?

    expr 命令将包含空格的字符串视为多个参数,而不是一个整体,因此无法进行正确的算术运算。

  2. 三种解决方案中哪种效率最高?

    使用 Shell 内置算术扩展 $((...)) 的效率最高,因为它不需要调用外部命令或进行管道操作。

  3. 如果我的数字字符串中包含非数字字符怎么办?

    你需要先对字符串进行处理,去除非数字字符,可以使用 trsed 等命令实现。

  4. 除了上述三种方法,还有其他解决方法吗?

    还可以使用 awkperl 等工具进行处理,但相对来说比较复杂。

  5. 如何避免出现 "expr: non-integer argument" 错误?

    在编写 Shell 脚本时,尽量使用 Shell 内置的算术扩展 $((...)) 进行算术运算,并注意变量类型的检查,避免将非数字字符串传递给 expr 命令。