Shell脚本中如何比较数组值?代码排错及数组值类型疑问解答
Shell脚本问题解答
问题1:故障代码的错误原因及修复方案
核心错误点
代码存在3处核心问题,直接导致运行异常:
- 数组读取逻辑完全错误
开头写的read a arr是将输入的第一个单词赋值给普通变量a,第二个单词赋值给普通变量arr,根本不会生成预期的数组a。此时用${a[1]}、${a[2]}取值只能得到空值,后续算术比较会直接报"需要二元运算符"的错误。 - if判断存在空值风险
代码if [ ${a[1]} -gt ${a[2]} ] ;中,如果a[1]或a[2]为空、或者是非合法整数字符串,-gt算术比较会直接报错,无法执行。 - for循环逻辑写反
代码for (( b=0; b > ${a[2]}; b++));的判断条件完全颠倒:初始化b=0,如果a[2]是正整数,0永远不满足"大于a[2]"的条件,循环一次都不会执行。
修复方案
按以下步骤修改即可正常运行:
- 将开头的输入读取逻辑改为
read -a a,表示将输入内容按空格拆分后存入数组a - 给数组取值增加默认值和引号,避免空值报错:把
${a[1]}改为"${a[1]:-0}",${a[2]}改为"${a[2]:-0}",空值时默认用0填充 - 修正for循环的判断条件,如果要循环
a[2]次,把b > ${a[2]}改为b < ${a[2]}
修复后完整代码
#!/bin/bash # 正确读入数组 read -a a if [ "${a[0]:-0}" -ne 1 ] && [ "${a[0]:-0}" -ne 2 ] && [ "${a[0]:-0}" -ne 3 ]; then echo "Ne poznam vrednosti prvega parametra" echo "Konec skripte" else if [ "${a[0]:-0}" -eq 1 ]; then echo "Prvi parameter ima vrednost ${a[0]}" # 增加空值兼容 if [ "${a[1]:-0}" -gt "${a[2]:-0}" ] ; then echo "Drugi parameter je vecji ali enak tretjemu parametru." else echo "Drugi parameter ni vecji ali enak tretjemu parametru." fi fi if [ "${a[0]:-0}" -eq 2 ]; then echo "Prvi parametar ima vrednost: 2" # 修正循环条件 for (( b=0; b < "${a[2]:-0}"; b++)); do echo "WORKS" done fi fi
问题2:Shell数组值的处理类型
Bash属于弱类型语言,所有变量默认存储为字符串类型,具体按文本还是整数处理完全取决于你使用的操作符:
- 当你使用
-gt/-lt/-eq这类算术比较符、$(( ))算术展开、(( ))算术判断语法时,Shell会尝试将变量值转换为整数处理,如果变量值不是合法整数会直接报错 - 当你使用
[[ ]]中的>/</==这类比较符时,会按字符串的字典序做文本比较
举个简单例子:如果数组值是20和100,用[ 20 -gt 100 ]做整数比较返回假,用[[ 20 > 100 ]]做字符串比较返回真(因为字符'2'的ASCII码大于'1')。
内容的提问来源于stack exchange,提问作者Martin Cernak
相关产品推荐
相关产品推荐

