Bash 商店「$@&引用;添加到一个变量以供以后使用,与带引号的参数有关

Bash 商店「$@&引用;添加到一个变量以供以后使用,与带引号的参数有关,bash,Bash,我有一本书。接口的一部分要求用户使用间接层调用bash函数,如下所示: require some_fun "arg 1" "arg 2" 它执行一些有趣的“arg 1”和“arg 2”(然后做一些额外的事情,这就是它存在的原因)。目前,我只是调用“$@”来完成这项工作,一切正常 我现在需要将这些函数调用推迟到以后,但在Bash中找不到这样做的方法。实际上,每次调用require时,我都想将“$@”推到堆栈上,然后循环该堆栈并执行参数,就像我当前的行为一样。这需要多维数组,而bash不支持多维数

我有一本书。接口的一部分要求用户使用间接层调用bash函数,如下所示:

require some_fun "arg 1" "arg 2"
它执行
一些有趣的“arg 1”和“arg 2”
(然后做一些额外的事情,这就是它存在的原因)。目前,我只是调用
“$@”
来完成这项工作,一切正常

我现在需要将这些函数调用推迟到以后,但在Bash中找不到这样做的方法。实际上,每次调用
require
时,我都想将
“$@”
推到堆栈上,然后循环该堆栈并执行参数,就像我当前的行为一样。这需要多维数组,而bash不支持多维数组,因此我尝试以下方法:

require() {
  dep_num=${#SK_deps[@]}
  dep_var="SK_dep_$dep_num"
  eval $dep_var="$@"
  SK_deps+=($dep_var)
}
它基本上生成一个变量来存储“$@”,并将变量名放入
$SK_deps

然后,我尝试使用以下方法迭代列表:

for dep_var in ${SK_deps[@]}
do
  ${!dep_name}
done
但这似乎打破了引用的论点,因此:

require some_fun "arg 1" "arg 2"
被解释为:

require some_fun arg 1 arg 2
没有引用


有什么办法可以做我想做的事吗?使用“$*”也会导致报价定位丢失。感觉在Bash中应该有一种方法可以做到这一点,而不必使用sed/awk进行黑客攻击。

在扩展阵列时引用阵列:

for dep_var in "${SK_deps[@]}"
do
  ${!dep_name}
done
此外,下面这句话似乎很可疑:

eval $dep_var="$@"

试着用
set-xv
运行你的脚本,看看变量是如何真正扩展的。

我发现了一个使用eval的非常难看的解决方案,因此任何更好的建议都将不胜感激

require() {
  local tmp_var=""
  for arg in "$@"
  do
    tmp_var="$tmp_var \"$arg\""
  done
  SK_deps+=("$tmp_var")
}
然后:


很明显,像这样使用eval充满了边缘情况,例如args中已经有引号,或者args中已经有反斜杠等等。

eval解决方案并没有那么糟糕。关键是利用
printf
shell quoted机制,它将为您处理所有棘手的情况:

require() {
    local quoted
    printf -v quoted ' %q' "$@"
    SK_deps+=("$quoted")
}
然后您可以正常运行它:

for dep in "${SK_deps[@]}"; do eval $dep; done

$SK_deps
只是一个变量名数组,而不是参数本身。它只是填充了字符串,如
SK_dep_0
SK_dep_5
)我想我已经找到了一个解决方案(至少在我的头脑中),它可以存储
$
$1,$2$n
分别。是的,我一直在输出扩展,它肯定缺少引号。我还尝试了
eval$dep\u var=\“$@\”
,这样引号就在eval中了,但没有用。太棒了。我不知道这个存在。稍后将尝试:)
for dep in "${SK_deps[@]}"; do eval $dep; done