对于“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
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 42
可移植到所有 POSIX shell:
if [ -n "${foobar+1}" ]; then
echo "foobar is defined"
else
echo "foobar is not defined"
fi
Run Code Online (Sandbox Code Playgroud)
作出这样的${foobar:+1},如果你想治疗foobar以同样的方式是否为空或没有定义。您还可以${foobar-}在foobar未定义时获取空字符串,foobar否则获取空字符串(或在 之后放置任何其他默认值-)。
在 ksh 中,如果foobar已声明但未定义,如在 中typeset -a foobar,则${foobar+1}扩展为空字符串。
Zsh 没有声明但未设置的变量:typeset -a foobar创建一个空数组。
在 bash 中,数组的行为方式不同且令人惊讶。${a+1}仅扩展为1如果a是非空数组,例如
typeset -a a; echo ${a+1} # prints nothing
e=(); echo ${e+1} # prints nothing!
f=(''); echo ${f+1} # prints 1
Run Code Online (Sandbox Code Playgroud)
相同的原则适用于关联数组:如果数组变量具有非空索引集,则将其视为已定义。
测试是否已定义任何类型的变量的另一种特定于 bash 的方法是检查它是否在. 这与定义不同,报告空数组,但报告声明但未分配的变量 ( ) 为未定义。${!PREFIX*}${foobar+1}unset foobar; typeset -a foobar
case " ${!foobar*} " in
*" foobar "*) echo "foobar is defined";;
*) echo "foobar is not defined";;
esac
Run Code Online (Sandbox Code Playgroud)
这等效于测试typeset -p foobaror的返回值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.
总结 Gilles 的回答,我制定了以下规则:
[[ -v foobar ]]中的Bash版本> = 4.2变量。declare -p foobar &>/dev/null中的Bash版本<4.2数组变量。(( ${foo[0]+1} ))或(( ${bar[foo]+1} ))用于索引 ( -a) 和键控 ( -A) 数组 ( declare) 的下标。选项 1 和 2 在这里不起作用。| 归档时间: |
|
| 查看次数: |
51834 次 |
| 最近记录: |