[Solved] Variable Name as a Prompt

Dear Members,

I have an variable by name dir.If i do echo $dir i will get the path (/usr/bin/).

I am writing a shell script which will prompt to enter the variable name if run.Suppose the script name is test.sh.

If run test.sh it will prompt for entering variable name which is dir.Suppose if i do echo $dir inside the shell script it is not giving me the path.looks like it passing the value entered as a literal string.

How can i get the actual value of variable dir inside the script.

Following is my code inside the shell script:

VariableName()
{
        echo "***************************************"
        echo -n "Please Enter Variable Name : "
        read Read_VariableName
}

VariableName
echo $Read_VariableName

Thanks
Sandeep

Please post what Operating System and version you are running and what Shell you use.

If I guess that you have a Shell which creates a sub-shell for a function then variables become local to that function.
A common circumvention is:

EDIT: This script does not work! Ignore it.

VariableName()
{
        echo "***************************************"
        echo -n "Please Enter Variable Name : "
        read Read_VariableName
        echo "${Read_VariableName}"
}

VariableName | read Read_VariableName

echo "${Read_VariableName}"

I don't think that works in anything but ksh, since other shells will put the read in a subshell, too...

Another way to do so is a temporary file.

We are using Linux 2.6.9-78.0.13.0.1.ELsmp x86_64.

The shell is ksh.

Thanks
Sandeep

---------- Post updated at 10:19 PM ---------- Previous update was at 10:12 PM ----------

methyl,

I tried your method but it is not working. The result is the same as input.

If you have any other idea please let me know.

Thanks
Sandeep

Have a go with this:

#!/usr/bin/env ksh
function VariableName
{
        echo "***************************************" >&2
        printf "Please Enter Variable Name : " >&2
        read Read_VariableName
        echo "${Read_VariableName}"
}


VariableName | read Read_VariableName

echo "${Read_VariableName}"

Your main problem is that your echo commands, which you assumed were going to the tty, were going to the read in the main body of the script. By redirecting them to stderr, the prompt and other information go to the tty, while the echo goes into VariableName.

You could also code

Read_VariableName=$( VariableName )

since you are only capturing the output into a single variable. This would work in bash as well as kshell. The echo/printf commands still need to be redirected; it's just an alternate approach.

I changed your echo -n to a printf command. Echo has so many different implementations that when I need to do something other than normal (e.g. adding the -n) I use printf. Just a preference of mine and no real bearing here.

---------- Post updated 04-27-12 at 00:10 ---------- Previous update was 04-26-12 at 23:51 ----------

I did have a go with your original script, and regardless of function definition style, function name, or name() , it works for me in both Kshell and bash. Given that your kernel seems pretty old, I'm wondering if you don't have a very old shell too. If you continue to have issues, it might be interesting to know what version of the shell you are running. Try excuting the command echo ${.sh.version} at the command line, or ksh --version .

WARNING! eval when used like this can be dangerous. See a few posts below for more info!

Are you trying to do something like this:

#!/bin/ksh

dir="/usr/bin"

VariableName()
{
        echo "***************************************"
        echo "Please Enter Variable Name : "
        read Read_VariableName
}

VariableName
eval echo \$$Read_VariableName


exit 0
$ x
***************************************
Please Enter Variable Name :
dir
/usr/bin
$

eval first replaces $Read_VariableName with "dir", then echo sees "$dir".

If the O/P has ksh as stated in a reply to one of the questions, the original script in post #1 should work. We need the O/P to check which Operating System and Shell is actually in use here.

Hi Gary,

Your Method worked. Thanks a ton for your help.

Thanks
Sandeep

I was thinking about this during lunch and realized this is very dangerous though. The way it is written right now, with eval working on user input with no validation, it would execute a command passed to it. You need to be careful and add validation to allow only one of a known list of variables to be entered. Or look for a different way to accomplish the same thing. Try this to see for yourself:

$ x
***************************************
Please Enter Variable Name :
`ls -lar`
$total 8 -rwxrwx--x 1 user1 zx 233 Apr 27 09:13 x drwxr-xr-x 21 user1 zx 2048 Apr 23 16:02 .. drwxrwx--- 2 user1 1024 Apr 25 10:37 .
$

Someone devious could wreak havoc!

In this case, devious.sh just runs a shell script that does a query to the database, but you see how this could be very dangerous:

x
***************************************
Please Enter Variable Name :
`devious.sh`
$ SYSDATE ----------- 27-APR-2012
$

It would be safer to assign the values to an associative array making eval unnecessary and allowing for fairly simple verification of a valid name entered.

#!/usr/bin/env ksh

function prompt
{
    read vname?"Enter a variable name: "
    return 0
}

typeset -A paths
paths[dir]=/tmp/dir
paths[bar]=/tmp/bar
paths[foo]=/tmp/foo

while prompt
do
    if [[ -z $vname ]]
    then
        exit
    fi

    if [[ -z ${paths[$vname]} ]]
    then
        echo "not a valid variable name: $vname"
    else
        echo "the path associated with $vname is: ${paths[$vname]}"
    fi
done