0
#!/bin/bash

testFunction () {
read -p "Question" $1
echo $1
}

testFunction foo

My intention is for read to assign the user input to the variable in the argument, and then echo it out, however instead of echoing user input it echos foo.

I realize to get around this I can use Bash indirection like so:

#!/bin/bash

testFunction () {
read -p "Question" $1
echo ${!1}
}

testFunction foo

However, I would prefer to avoid using this method since not all languages have variable indirection (and I will be moving onto a new language soon enough). Is there any other way I can make it look at foo as if it was a variable? Thanks.

4
  • Do you really believe that other languages will support any other forms of indirection that could be used in bash? Commented Sep 10, 2011 at 8:36
  • Well, if they don't then, how would this problem be solved in another language? Commented Sep 10, 2011 at 8:44
  • what's the point of all of this? why do you do it? Commented Sep 10, 2011 at 8:47
  • Although I find that slightly irrelevant to my question, I'll humor you by saying that it's a for a yes/no function I've made (since I had several yes/no functions in my program). I want the yes/no function to be able to check if the user input is equal to [Yy] or [Nn] and then act accordingly. Commented Sep 10, 2011 at 8:48

3 Answers 3

2

In any language that has a eval-like construct it is possible to interpret a string as a variable name. In Bash:

eval echo \$$foo

In Python:

from __future__ import print_function
eval ( "print (" + foo + ")" )

In most languages that lack eval this is not possible.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the input, as Python is actually the next language I will be learning.
But you wouldn't do it that way in Python regardless; you'd use a dict.
0

this is what I would do (based on your comment):

testFunction () {
  read -p "yes or no? [YynN] "  bla
  if [ "$bla" = 'Y' -o "$bla" = 'y' ]; then
      return 0
  fi
  return 1
}

if testFunction; then
  echo "it was yes"
fi

or

testFunction () {
  read -p "yes or no? [YynN] "  bla
  if [ "$bla" = 'Y' -o "$bla" = 'y' ]; then
      echo 1
  else
      echo 0
  fi
}

foo=`testFunction`
echo $foo

3 Comments

I still need to dynamically define what variable read will store user input in as opposed to having a fixed variable (bla).
you're still trying to do it at the wrong place. if you do want to do it in the function you have to use indirection.
Tangentially, the conditional can be made more elegant using case than this if [ construct.
0

You do can do this with eval

testFunction () {
    eval 'read -p "Enter Y or N: " '$1
    eval 'echo $'$1
}

testFunction foo

But eval is not a tool to be used lightly. What you're doing is probably crazy. You should be using an approach like this

testFunction () {
    read -p "Enter Y or N: " bar
    case "$bar" in
        [YyNn]) return 0 ;;
    esac
    return 1
}

testFunction && foo=valid

This way you don't have to re-check $foo later, its value is an answer to the question "Was the input valid?"

But maybe you want, later, to actually do something different based on whether the user said y or n, which I suspect is what drives this "Let's dynamically create a variable from a function" nonsense. In that case you can do something like

testFunction () {
    read -p "Enter Yes or No: " bar
    case "$bar" in
        [Yy][Ee][Ss]|[Yy]) printf y ;;
        [Nn][Oo]|[Nn]) printf n ;;
    esac
}

foo=$(testFunction)

This is functionally similar to the eval version, but it assures that you only get known values into foo. Later you can test the value in foo.

if [ -z "$foo" ] ; then
        echo invalid input
elif [ "$foo" = "y" ] ; then
        echo answered yes
elif [ "$foo" = "n" ] ; then
        echo answered no 
fi

And you can keep this code simple, because all possible values are already known.

2 Comments

Make more sense to return 0 for yes and 1 for no, maybe loop on invalid input, but that depends a lot on the application - for a reusable function, provide an option.
@tripleee: Agreed on all points, but I question the value of completeness and correctness for contrived examples which are as speculative as this. Given a clearer request I'd provide a better answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.