如果我想执行一些给定变量未设置的命令,我正在使用:
if [[ -z "$a" || -z "$v" ]]
then
echo "a or b are not set"
fi
然而相同的语法不适用于-v
,我必须使用:
if [[ -v a && -v b ]]
then
echo "a & b are set"
fi
这背后的历史是什么?我不明白为什么语法不一样。我读过这-v
是 bash 最近添加的内容(4.2)?
答案1
测试操作员-v
和-z
只是不一样。
运算符-z
判断字符串是否为空。因此,确实[[ -z "$a" ]]
会给出“变量未设置”的良好近似值a
,但不是完美的近似值:
a
如果设置为空字符串而不是取消设置,则表达式将产生 true ;a
如果未设置并且nounset
启用了该选项,则封闭脚本将失败。
另一方面,即使在边缘情况下,-v a
也将准确地“a
设置变量”。应该清楚的是,传递$a
而不是a
to
-v
是不正确的,因为它会在测试操作员看到它之前扩展可能未设置的变量;因此,检查该变量(由其名称指向)并判断它是否已设置必须是该操作员任务的一部分。
答案2
-z
和 的含义有所不同-v
:
echo Empty:
x="" # Same with x=
[[ -z $x ]] && echo z
[[ -v x ]] && echo v
unset x
echo Unset
[[ -z $x ]] && echo z
[[ -v x ]] && echo v
通过使用-z
,您无法区分分配了空值的变量和未分配任何值的变量。
另外,[[ -z $x ]]
仍然是明智的set -u
,而[[ -v x ]]
不是。