Вы правы, 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.' то выход будет «Полная луна исчезнет, и небо станет ясным, поэтому оборотень должен быть активным».
Мне интересно, почему вы хотите сделать это или то, что вы на самом деле пытаетесь достичь. Иногда 'eval' является правильным или единственным способом, но есть и специальные функции' declare' и 'printf', которые могут быть полезны. И могут быть другие способы добиться того, что вам нужно. –
У меня есть сценарий bash, который я хочу настроить. Я хочу, чтобы у пользователя была возможность указать «шаблон». Позже некоторые переменные в шаблоне будут заменены действиями, выполняемыми скриптом (запросы SQL, вызовы SOAP и другие внутренние утилиты) и передаются в другую программу командной строки. Я несколько новичок в Bash, и что-то об этом подходе просто кажется неправильным. Спасибо, что спросили подробности. – User1