【问题标题】:Parameterized substitutions (${foo%bar}, ${foo-bar}, etc) without using eval不使用 eval 的参数化替换(${foo%bar}、${foo-bar} 等)
【发布时间】:2016-11-14 18:10:33
【问题描述】:

来自envsubst男人:

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

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

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

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

【问题讨论】:

    标签: bash shell environment-variables eval


    【解决方案1】:

    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 的转义符之间存在一些冲突。

    【讨论】:

    • 我不像以前那么喜欢${foo@P}。我不知道命令替换的扩展是错误还是必要的邪恶。
    • 我已经提交了错误报告;至少,手册页应该明确说明代码执行的可能性。
    • 提示字符串总是扩展命令替换;目前尚不清楚您是否可以在“真实”交互式 shell 之外强制扩展提示(使用 bash -i 运行命令是不够的),但新参数扩展运算符似乎确实是个问题。
    • @chepner 你能分享一个你已经填补的错误的链接吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2014-03-20
    • 1970-01-01
    • 2020-10-03
    • 2017-06-23
    • 2017-07-25
    • 1970-01-01
    相关资源
    最近更新 更多