
Я пишу скрипт оболочки для терминала Linux. Я хочу иметь возможность вводить имена переменных в приглашение. Например:
тест.ш:
test="Monkey in the middle..."
read -p "Enter input: " input
echo $input
выход:
Enter input: $test
$test
Я хочу иметь возможность вводить «$test» во время read -p
сегмента подсказки скрипта и чтобы скрипт вывел «Monkey in the middle...» в конце вместо того, чтобы выводить «$test», как сейчас.
Как бы я это сделал?
ОБНОВЛЯТЬ:
Используя ответы, предоставленные мне здесь и вэта тема(большое спасибо всем участникам и комментаторам!), мне удалось собрать воедино эту строку, которая очень хорошо мне подошла:
newvariable="$(eval echo $input)"
Будьте осторожны, меня не раз предупреждали, что использование eval может представлять угрозу безопасности. Помните об этом, если выберете это решение.
решение1
Вместо
echo "$input"
пытаться
eval echo "$input"
Он даже не специфичен для bash, работает в /bin/sh!
Обратите внимание, что это представляет серьезную угрозу безопасности, поскольку eval
просто выполняет то, что вы ему даете. В этом случае оболочка интерпретирует строку $input
как $test
, а затем eval
выполняет echo $test
. Но что, если пользователь введет $test; rm -rf *
? , eval
то будет представлено echo $test; rm -rf *
. Будьте очень осторожны, если вы это сделаете.
решение2
В bash вы можете использоватькосвенное расширение параметрасинтаксис:
test="Monkey in the middle..."
read -p "Enter input: " input
echo ${!input}
В этом случае пользователю необходимо указать test
только строку без предшествующего знака доллара.
решение3
Если вас не смущает, что пользователь может выполнять произвольные команды, включив подстановку команды $(…)
, вы можете отправить строку во eval
встроенную функцию. Обратите внимание, что eval
ожидает фрагмент оболочки, и если входные данные содержат кавычки, они могут вызвать синтаксические ошибки. (Относительно) простой способ справиться с кавычками — использовать документ here для выполнения подстановок. Вы все еще находитесь во власти незавершенной переменной или подстановки команды (например, $(foo
).
IFS= read -r -p "Enter input: " input
eval "string=\$(cat <<EOF
_${input}
EOF
)"
string=${string#_}