对于“ GNU bash,版本4.2”之前的Bash版本-v,该test命令的选项是否具有等效的替代品?例如:
shopt -os nounset
test -v foobar && echo foo || echo bar
# Output: bar
foobar=
test -v foobar && echo foo || echo bar
# Output: foo
对于“ GNU bash,版本4.2”之前的Bash版本-v,该test命令的选项是否具有等效的替代品?例如:
shopt -os nounset
test -v foobar && echo foo || echo bar
# Output: bar
foobar=
test -v foobar && echo foo || echo bar
# Output: foo
Answers:
可移植到所有POSIX外壳:
if [ -n "${foobar+1}" ]; then
echo "foobar is defined"
else
echo "foobar is not defined"
fi
作出这样的${foobar:+1},如果你想治疗foobar以同样的方式是否为空或没有定义。${foobar-}当foobarundefined 时,您还可以使用来获取空字符串,foobar否则使用值(或在后面放置其他任何默认值-)。
在ksh中,如果foobar像一样在声明但未定义typeset -a foobar,则${foobar+1}扩展为空字符串。
Zsh没有声明但未设置的变量:typeset -a foobar创建一个空数组。
在bash中,数组的行为方式不同而令人惊讶。${a+1}仅扩展为1if a为非空数组,例如
typeset -a a; echo ${a+1} # prints nothing
e=(); echo ${e+1} # prints nothing!
f=(''); echo ${f+1} # prints 1
同样的原则适用于关联数组:如果数组变量具有一组非空的索引,则将它们视为已定义。
测试是否定义了任何类型的变量的另一种特定于bash的方式是检查是否在中列出了该变量。这会报告定义为空的数组,这与不同,但是会将声明但未分配的变量()报告为未定义。${!PREFIX*}${foobar+1}unset foobar; typeset -a foobar
case " ${!foobar*} " in
*" foobar "*) echo "foobar is defined";;
*) echo "foobar is not defined";;
esac
这等效于测试typeset -p foobar或的返回值declare -p foobar,除了typeset -p foobar在声明但未分配的变量上失败之外。
在bash中,与在ksh中一样,set -o nounset; typeset -a foobar; echo $foobar在尝试扩展未定义变量时触发错误foobar。与ksh不同,set -o nounset; foobar=(); echo $foobar(或echo "${foobar[@]}")还会触发错误。
请注意,在此处描述的所有情况下,${foobar+1}当且仅当$foobar会导致下的错误时,才扩展为空字符串set -o nounset。
echo "${foobar:+1}"中,1如果declare -a foobar先前已发行,则不会打印,因此foobar是一个索引数组。declare -p foobar正确报告declare -a foobar='()'。是否"${foobar:+1}"只适用于非数组变量的工作?
${foobar+1}(不带:,我在原始答案中倒了两个例子)对于bash中的数组是正确的。如果您的定义不同,bash有点奇怪。看到我更新的答案。$foobarset -o nounset
0为定义索引或键a=(),则${a+1}正确不返回任何内容。
defined运算符。 Test 可以做到这一点;它不可能是困难的(呃 ......)
我对bash中的所有变量使用了相同的技术,并且可以正常工作,例如:
[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"
输出:
foobar is unset
同时
foobar=( "val" "val2" )
[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"
输出:
foobar is set
foobar=""然后将进行报告foobar is unset。等等,我把它拿回来。实际上,仅测试第一个元素是否为空,因此,如果您知道变量不是数组,并且只关心空性而不是定义性,那似乎只是一个好主意。
-v不是的选项test,而是条件表达式的运算符。