使用字符串变量在 If 语句中测试 -lt 命令

使用字符串变量在 If 语句中测试 -lt 命令

我正在研究 bash 中的 If 语句,发现了一些意外的行为。

假设我有一个变量b=2。它显然是一个字符串。如果我执行如下 if 语句:

if [ $((b)) -lt 5 ]
then
...
fi

它成功通过了条件语句,因为 2 确实小于 5。但是,如果我删除双括号 ( if [ b -lt 5 ]),它仍然像之前的示例一样工作。你能告诉我为什么会这样吗?我认为这只-lt适用于整数,不适用于字符串。它是否在这里将字符串变量隐式转换为整数类型?

答案1

Bash 变量本质上是无类型的1 - 如果值无法成功转换,则仅对特定类型有意义的测试可能会在评估时失败。算术测试的有效形式为:

$ b=4; if [ $b -lt 5 ]; then echo "less"; fi
less

或(使用算术表达式语法)

$ b=4; if (( $b < 5 )); then echo "less"; fi
less

如 部分所述ARITHMETIC EVALUATIONman bash$上下文中可以省略取消引用(( ... ))

Shell 变量被允许作为操作数;在表达式求值之前执行参数扩展。 在表达式中,shell 变量也可以通过名称引用,而无需使用参数扩展语法

所以

$ b=4; if (( b < 5 )); then echo "less"; fi
less

同样是不是在 POSIX[ ]测试语法中为 true,它将被视为b字符串文字:

$ b=4; if [ b -lt 5 ]; then echo "less"; fi
-bash: [: b: integer expression expected

如果你尝试[ ]对包含非数字的变量执行算术测试价值它会因同样的原因而失败,即该值不能转换为数字类型:

$ b=foo; if [ $b -lt 5 ]; then echo "less"; fi
-bash: [: foo: integer expression expected

1declare -i如果-u设置了 shell 选项,则可以使用它来实现基本的类型检查。

$ set -u
$ declare -i b
$ b=foo
bash: foo: unbound variable
$ echo $?
1

而分配有效的数值

$ b=4
$ echo $?
0

成功。

相关内容