【问题标题】:Lazy Evaluation in BashBash 中的惰性求值
【发布时间】:2011-02-23 10:46:54
【问题描述】:

是否有比以下更优雅的惰性求值方式:

模式='$x 和 $y' x=1 y=2 评估“回声$模式”

结果:

1 和 2

它有效,但eval "echo ..." 只是感觉草率,并且可能在某些方面不安全。在 Bash 中有没有更好的方法来做到这一点?

【问题讨论】:

  • 我很好奇你为什么要这样做,或者你实际上想要完成什么。有时eval 是正确的或唯一的方法,但declareprintf 的特殊功能也可能有用。并且可能还有其他方法可以完成您所追求的目标。
  • 我有一个想要配置的 bash 脚本。我希望用户能够指定“模式”。稍后,模式中的一些变量将被脚本运行的活动(SQL 查询、SOAP 调用和其他内部实用程序)替换并传递给另一个命令行程序。我对 Bash 有点陌生,这种方法的某些东西感觉不对。感谢您询问更多详细信息。

标签: bash lazy-evaluation


【解决方案1】:

您可以使用gettext 中的命令envsubst,例如:

$ pattern='x=$x and y=$y'
$ x=1 y=2 envsubst <<< $pattern
x=1 and y=2

【讨论】:

  • 我认为这种情况下的安全问题有点偏执。我喜欢额外的引号。
【解决方案2】:

一种安全的可能性是使用函数:

expand_pattern() {
    pattern="$x and $y"
}

就是这样。然后按如下方式使用:

x=1 y=1
expand_pattern
echo "$pattern"

您甚至可以使用xy 作为环境变量(这样它们就不会设置在主范围内):

x=1 y=1 expand_pattern
echo "$pattern"

【讨论】:

  • 如果它还没有出现,这就是我要写的答案。 (话又说回来,我只是因为添加了答案才发现这个问题,将其弹回首页)。 :)
【解决方案3】:

你说得对,eval 在这种情况下存在安全风险。这是一种可能的方法:

pattern='The $a is $b when the $z is $x $c $g.'    # simulated input from user (use "read")
unset results
for word in $pattern
do
    case $word in
        \$a)
            results+=($(some_command))   # add output of some_command to array (output is "werewolf"
            ;;
        \$b)
            results+=($(echo "active"))
            ;;
        \$c)
            results+=($(echo "and"))
            ;;
        \$g)
            results+=($(echo "the sky is clear"))
            ;;
        \$x)
            results+=($(echo "full"))
            ;;
        \$z)
            results+=($(echo "moon"))
            ;;
          *)
            do_something    # count the non-vars, do a no-op, twiddle thumbs
            # perhaps even sanitize %placeholders, terminal control characters, other unwanted stuff that the user might try to slip in
            ;;
    esac
done
pattern=${pattern//\$[abcgxz]/%s}    # replace the vars with printf string placeholders
printf "$pattern\n" "${results[@]}"  # output the values of the vars using the pattern
printf -v sentence "$pattern\n" "${results[@]}"  # put it into a variable called "sentence" instead of actually printing it

输出将是“当满月天晴时狼人处于活动状态。”同样的程序,如果模式是“$x $z 超出 $c $g,所以 $a 必须是 $b”。那么输出将是“满月出来,天空晴朗,所以狼人一定是活跃的。”

【讨论】:

  • 答案与问题的示例相匹配。但是对于比基本字符串替换更复杂的事情,它似乎不是很有用。如果我尝试遵循这种方法,我必须在 Bash 中编写一个 Bash 解释器。
  • 我的回答是将脚本与用户的不可信输入隔离开来。它基于 OP 对问题的评论,以回应我的查询。
猜你喜欢
  • 1970-01-01
  • 2013-12-30
  • 2020-05-19
  • 2016-10-11
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多