Lazy Evaluation in Bash

时光怂恿深爱的人放手 提交于 2019-12-18 04:00:11

问题


Is there more elegant way of doing lazy evaluation than the following:

pattern='$x and $y'
x=1
y=2
eval "echo $pattern"

results:

1 and 2

It works but eval "echo ..." just feels sloppy and may be insecure in some way. Is there a better way to do this in Bash?


回答1:


You can use the command envsubst from gettext, for example:

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



回答2:


One safe possibility is to use a function:

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

That's all. Then use as follows:

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

You can even use x and y as environment variables (so that they are not set in the main scope):

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



回答3:


You're right, eval is a security risk in this case. Here is one possible approach:

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

The output would be "The werewolf is active when the moon is full and the sky is clear." The very same program, if the pattern is 'The $x $z is out $c $g, so the $a must be $b.' then the output would be "The full moon is out and the sky is clear, so the werewolf must be active."



来源:https://stackoverflow.com/questions/2900707/lazy-evaluation-in-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!