Bash 中的惰性求值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2900707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Lazy Evaluation in Bash
提问by User1
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?
它有效,但eval "echo ..."只是感觉马虎,并且可能在某些方面不安全。有没有更好的方法在 Bash 中做到这一点?
采纳答案by tokland
回答by gniourf_gniourf
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 xand yas environment variables (so that they are not set in the main scope):
您甚至可以使用x和y作为环境变量(这样它们就不会在主范围内设置):
x=1 y=1 expand_pattern
echo "$pattern"
回答by Paused until further notice.
You're right, evalis a security risk in this case. Here is one possible approach:
你是对的,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
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."
输出将是“狼人在满月且天空晴朗时处于活动状态。” 完全相同的程序,如果模式是“$x $z 出 $c $g,所以 $a 必须是 $b。” 然后输出将是“满月出来,天空晴朗,所以狼人一定是活跃的。”

