user880248
user880248

Reputation:

Bash script variable not string

#!/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.

Upvotes: 0

Views: 1071

Answers (3)

sorpigal
sorpigal

Reputation: 26106

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.

Upvotes: 0

Karoly Horvath
Karoly Horvath

Reputation: 96306

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

Upvotes: 0

n. m. could be an AI
n. m. could be an AI

Reputation: 120079

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.

Upvotes: 2

Related Questions