在bash中间接variables赋值

似乎在bash中进行间接variables设置的推荐方法是使用eval

 var=x; val=foo eval $var=$val echo $x # --> foo 

问题是通常与eval

 var=x; val=1$'\n'pwd eval $var=$val # bad output here 

(因为在很多地方都推荐它,所以我想知道有多less个脚本因为这个而变得脆弱)

在任何情况下,使用(转义)引号的显而易见的解决scheme实际上并不工作:

 var=x; val=1\"$'\n'pwd\" eval $var=\"$val\" # fail with the above 

事情是,bash有间接variables引用(在${!foo} ),但我没有看到任何这样的方式来进行间接赋值 – 有没有什么理智的方法来做到这一点?

为了logging,我find了一个解决scheme,但这不是我认为是“理智”的东西…:

 eval "$var='"${val//\'/\'\"\'\"\'}"'" 

重点是推荐的方法是:

 eval "$var=\$val" 

RHS也是间接完成的。 由于eval在相同的环境中使用,它将有$val绑定,所以推迟它的工作,现在它只是一个variables(具有已知名称),没有问题引用。

一个稍微好一点的方法是避免使用eval可能带来的安全隐患

 declare $var="$val" 

请注意, declarebash typeset的同义词。 typeset命令得到了更广泛的支持( kshzsh也使用它):

 typeset $var="$val" 

Bash对printf进行了扩展,将其结果保存到一个variables中:

 printf -v "${VARNAME}" '%s' "${VALUE}" 

这可以防止所有可能的转义问题。

如果您为$VARNAME使用无效标识符,则该命令将失败并返回状态码2:

 $ printf -v ';;;' foobar; echo $? bash: printf: `;;;': not a valid identifier 2