懒评价猛砸
是否有这样做懒的评价比下面的更优雅的方式:懒评价猛砸
pattern='$x and $y' x=1 y=2 eval "echo $pattern"
结果:
1 and 2
它的工作原理,但eval "echo ..."
只是觉得草率,并可能以某种方式不安全。在Bash中有更好的方法吗?
你说得对,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解释器。 – ceving 2014-10-21 08:49:09
我的答案是将脚本与用户的不可信输入隔离的一种方法。它基于OP针对我的查询附带的问题的评论。 – 2018-02-22 23:38:48
一个安全的可能性是使用的函数:
expand_pattern() {
pattern="$x and $y"
}
这就是全部。然后使用方法如下:
x=1 y=1
expand_pattern
echo "$pattern"
你甚至可以使用x
和y
作为环境变量(以使它们不在主范围设置):
x=1 y=1 expand_pattern
echo "$pattern"
这是我要写的,如果它还没有在这里的答案。 (再次,我根据已经添加的答案,将它弹回到首页,我完全发现了这个问题)。 :) – 2018-02-23 22:47:07
我很好奇,为什么你想干什么这或你实际上想要完成的是什么。有时''eval'是正确或唯一的出路,但'declare'和'printf'的特殊功能可能是有用的。而且可能还有其他方法可以完成你所追求的目标。 – 2010-05-24 23:28:19
我有一个bash脚本,我想要可配置。我希望用户能够指定一个“模式”。之后,模式中的一些变量将被脚本运行的活动(SQL查询,SOAP调用和其他内部实用程序)替换并传递给另一个命令行程序。对于Bash,我有点新鲜感,并且对这种方法感觉不对。感谢您询问更多细节。 – User1 2010-05-25 03:07:18