我正在研究 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 EVALUATION
,man 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
成功。