自bash
4.2起,添加了-v
条件表达式。它用于检查是否设置了变量(已分配值)。当编写在set -o nounset
下运行的脚本时,这是一个有用的工具,因为尝试使用未初始化的变量会导致错误。
我有一个问题,请参见POSIX bash
(set -o posix
)中的示例:
$ declare testvar=0
$ [ -v testvar ] && echo "It works!"
It works!
$ declare -A fizz=( [buzz]=jazz )
$ [ -v fizz[buzz] ] && echo "It works!"
It works!
$ [ -v fizz ] && echo "It doesn't work :("
$
如您所见,对常规变量使用-v
可以正常工作。使用它来检查关联数组中字段的存在也可以正常工作。但是,在检查关联数组本身的存在时,它不起作用。
那是为什么,并且有解决方法吗?
答案 0 :(得分:1)
如果您想知道它是否有任何条目,可以检查${#fizz[@]}
,但这并不能告诉您它是否被创建为空。您可以 将case语句或其他模式匹配与错误检查结合使用。
tst() { local tst;
(( $# )) || return # *minimal* error handling...
if tst="$(declare -p $1 2>&1)" # does the subshell error?
then case "$tst" in # if not, check the output
*\)*) (( $( eval echo \${#$1[@]} ) )) && # test number of entries
echo "Has Args" || # some implementations show '()'
echo "Empty but defined";; # some don't; this is for the *do*
*-A*) echo "Empty but defined";; # this is for the don't
*) echo ERROR;; # shouldn't get here
esac
else echo Undefined # if doesn't exist
fi
}
$: unset fizz
$: tst fizz
Undefined
$: declare -A fizz
$: tst fizz
Empty but defined
$: fizz[buzz]=jazz
$: tst fizz
Has Args
唐诺(Dunno)在您的上下文中有多大用处。 请注意,我是为关联数组显式编写的,它具有与该点不直接相关的最小错误检查。对于任何实际生产用途,都应该扩展很多。
我不喜欢eval
,但是我的bash版本没有名称引用。 :o /
答案 1 :(得分:0)
check4Associative() {
local foo typ
read foo typ foo < <(declare -p $1 2>&1)
[ "$typ" ] && [ -z "${typ//-*A*}" ]
}
您可以用作:
if check4Associative myVar; then ... ;fi
示例尝试:
unset fizz
check4Associative fizz && echo yes;echo $?
1
fizz=Blah
check4Associative fizz && echo yes;echo $?
1
declare -A fizz
check4Associative fizz && echo yes;echo $?
yes
0
fizz[foo]=bar
check4Associative fizz && echo yes;echo $?
yes
0
check4AssociativeArgs() {
local -n var=$1
local keys=(${!var[@]}) foo typ
read foo typ foo < <(declare -p $1 2>&1)
[ "$typ" ] && [ -z "${typ//-*A*}" ] &&
printf "Name: %s, type: %s, entry count: %d\n" $1 ${typ#-} ${#keys[@]}
}
然后
unset fizz
check4AssociativeArgs fizz ; echo $?
1
declare -A fizz
check4AssociativeArgs fizz
Name: fizz, type: A, entry count: 0
fizz[foo]=bar fizz[bar]=baz
check4AssociativeArgs fizz
Name: fizz, type: A, entry count: 2