Lazy Evaluation in Bash

前端 未结 3 1764
礼貌的吻别
礼貌的吻别 2020-12-16 14:49

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         


        
相关标签:
3条回答
  • 2020-12-16 15:03

    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
    
    0 讨论(0)
  • 2020-12-16 15:10

    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."

    0 讨论(0)
  • 2020-12-16 15:20

    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"
    
    0 讨论(0)
提交回复
热议问题