参数化替换($ {foo%bar},$ {foo-bar}等)而不使用eval

时间:2016-11-14 18:10:33

标签: bash shell environment-variables eval

来自envsubst男人:

  

这些替换是shell的替换子集   对未加引号和双引号的字符串执行。其他种类   由shell完成的替换,例如 $ {variable-default} 或   {em> $(命令列表)或`command-list` 不会由envsubst执行   程序,由于安全原因。

我想对字符串执行变量替换,支持${variable-default}${variable%suffix}等结构。我不想允许运行命令。

显然,使用envsubst是不可能的,另一方面eval会产生严重的安全隐患。

除了编写自定义插值函数之外还有其他可能吗?

1 个答案:

答案 0 :(得分:3)

bash 4.4引入了一种新型的参数扩展,它可以做你想要的。也就是说,${foo@P}扩展foo的值,就像它是一个提示字符串一样,并且提示字符串在显示之前就会进行一轮扩展。

${parameter@operator}
    Parameter transformation.  The expansion is either a transforma-
    tion  of  the  value of parameter or information about parameter
    itself, depending on the value of operator.  Each operator is  a
    single letter:

    Q      The  expansion is a string that is the value of parameter
           quoted in a format that can be reused as input.
    E      The expansion is a string that is the value of  parameter
           with  backslash  escape  sequences  expanded  as with the
           $'...' quoting mechansim.
    P      The expansion is a string that is the result of expanding
           the value of parameter as if it were a prompt string (see
           PROMPTING below).
    A      The expansion is a string in the form  of  an  assignment
           statement  or  declare  command  that, if evaluated, will
           recreate parameter with its attributes and value.
    a      The expansion is a string consisting of flag values  rep-
           resenting parameter's attributes.

一个简单的例子:

$ foo='${bar:-9}'
$ echo "$foo"
${bar:-9}
$ echo "${foo@P}"
9
$ bar=3
echo "${foo@P}"
3

但它仍然允许通过$(...)运行任意命令:

$ foo='$(echo hi)'
$ echo "${foo@P}"
hi

另一个警告:它当然也会扩展提示转义,因此如果你的字符串已经包含一些反斜杠,那么你可能会比预期更多的扩展。用于echo -e的提示转义和转义之间存在一些冲突。