是否有這樣做懶的評價比下面的更優雅的方式:懶評價猛砸
pattern='$x and $y' x=1 y=2 eval "echo $pattern"
結果:
1 and 2
它的工作原理,但eval "echo ..."
只是覺得草率,並可能以某種方式不安全。在Bash中有更好的方法嗎?
是否有這樣做懶的評價比下面的更優雅的方式:懶評價猛砸
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