我正在寻找一种干净的方法(不使用eval命令)来间接引用数组。下面是我想要的更精确的描述:
function valueof {
echo "indirection1 \$$1=${!1}"
eval "echo indirection2 \\\$$1=\${$1[@]}" # Untill this step its fine.
# My final objective is to do this (but eval is not a very sexy solution) :
for i in $(eval "echo \${$1[@]}") ; do
echo $i
done
# Here is the "problem", ie. "bad substitution"
echo "indirection3 \$$1=${!1[@]}"
# "1[@]" is evaluated first i guess?
}具有以下调用值:
a=("a" "aa" "aaa")
b=("b" "bb" "bbb")
valueof a
valueof b我得到的输出是:
indirection1 $a=a
indirection2 $a=a aa aaa
a
aa
aaa
indirection1 $b=b
indirection2 $b=b bb bbb
b
bb
bbb在stderr上:
prog.sh: line 10: indirection3 $1=${!1[@]}: bad substitution
prog.sh: line 10: indirection3 $1=${!1[@]}: bad substitution感谢您对此问题的回答/评论:)
发布于 2012-11-25 00:13:16
我建议从git devel分支构建Bash,并使用typeset -n,就像大多数其他具有数组的正常shell一样。所有其他涉及函数和数组的解决方案要么需要eval,要么需要利用奇怪的未记录行为。两者都需要同等的注意,并且两者之间不一定有优势。
下面是一个通用的示例,它演示了几乎所有可以在不使用eval的情况下间接执行的操作。命名空间冲突仍然是可能的。
isSubset() {
local -a 'xkeys=("${!'"$1"'[@]}")' 'ykeys=("${!'"$2"'[@]}")'
set -- "${@/%/[key]}"
(( ${#xkeys[@]} <= ${#ykeys[@]} )) || return 1
local key
for key in "${xkeys[@]}"; do
[[ ${!2+_} && ${!1} == "${!2}" ]] || return 1
done
}
a=(abc def [4]=ghi jkl)
b=(abc def [4]=ghi jkl)
c=(abc [3]=def [6]=ghi xyz)
isSubset a b
echo $? # 0
isSubset b c
echo $? # 1在某些方面,这实际上是伪装的eval。大多数人没有意识到,当他们将变量名传递给内置和算术表达式时,他们就是在有效地执行eval。您必须始终确保变量名称和索引是由内部控制的,并且永远不会受到用户输入或其他无法保证结果的副作用的影响。
从你对分词和引号的误用来看,你应该换一种不同的语言。Bash实际上不是用来处理安全封装的。
https://stackoverflow.com/questions/13541465
复制相似问题