5

I'm writing a shell-script for linux terminal. I want to be able to input variable names on a prompt. For example:

test.sh:

 test="Monkey in the middle..."
 read -p "Enter input: " input
 echo $input

output:

 Enter input: $test
 $test

I want to be able to input "$test" during the read -p prompt segment of the script and have the script echo "Monkey in the middle..." at the end instead of echo-ing "$test" as it does now.

How would I go about doing that?



UPDATE:

Using the answers provided to me here and in this thread (a big thanks to the contributors and commentators!), I managed to piece together this line which worked very well for me:

newvariable="$(eval echo $input)" 

Be, advised, I was warned more than once that using eval may pose a security risk. Keep that in mind if you opt for this solution.

3 Answers 3

4

Instead of

echo "$input"

try

eval echo "$input"

It's not even bash-specific, works on /bin/sh!

Note that this poses a serious security risk because eval just executes what you give it. In this case, the shell interprets the string $input as $test, and then eval executes echo $test. But what if the user entered $test; rm -rf *? eval would be presented with echo $test; rm -rf *. Be very careful if you do this.

6
  • Yes, this works!
    – miracle173
    Feb 15, 2016 at 7:38
  • Thanks so much, that worked for me too. How would I go about saving the output of eval echo $input as new variable? Feb 15, 2016 at 23:40
  • I found it, newvariable="$(eval echo $input)" will save the output of eval echo $input to newvariable. Feb 15, 2016 at 23:56
  • Combining $test with other strings is resulting in the error messages "unexpected EOF while looking for matching `'' and "syntax error: unexpected end of file". Any idea what could be causing that. For example, I tried to input: You've always been a $test which I was hoping would make You've always been a monkey in the middle Feb 16, 2016 at 0:04
  • 1
    Here's a solution. After you read in $input, do input=$(echo $input | sed "s/\'/\\\'/g" | sed 's/\"/\\\"/g'). After that, just use your eval expression as before.
    – Moonchild
    Feb 16, 2016 at 3:46
2

In bash you can use an indirect parameter expansion syntax:

test="Monkey in the middle..."
read -p "Enter input: " input
echo ${!input}

In this case user has to provide test string only without preceding dollar sign.

0
1

As long as you don't mind that the user can execute arbitrary commands by including a command substitution $(…), you can submit the string to the eval builtin. Note that eval expects a shell snippet, and if the input includes quotes, they may cause syntax errors. The (relatively) easy way to cope with quotes is to use a here document to perform the substitutions. You're still at the mercy of an unterminated variable or command substitution (e.g. $(foo).

IFS= read -r -p "Enter input: " input
eval "string=\$(cat <<EOF
_${input}
EOF
)"
string=${string#_}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .