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.

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.

  • Yes, this works! – miracle173 Feb 15 '16 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? – thebunnyrules Feb 15 '16 at 23:40
  • I found it, newvariable="$(eval echo $input)" will save the output of eval echo $input to newvariable. – thebunnyrules Feb 15 '16 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 – thebunnyrules Feb 16 '16 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. – Elronnd Feb 16 '16 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.

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#_}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.