LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   ksh scripting: dynamic variable naming (https://www.linuxquestions.org/questions/programming-9/ksh-scripting-dynamic-variable-naming-930088/)

bracken84 02-18-2012 01:44 PM

ksh scripting: dynamic variable naming
 
I have written a script for ksh successfully. This question is about using variables to name other variables on an echo command to validate my work, without having to hard-code each test output.

The script gathers information about folders in the current working directory and exports environment variables with the absolute path to those directories stored in each respectively. This is mainly accomplished by using a for loop and a counter. The test environment is a folder with two sub directories, call them dirA and dirB. When creating the environment variables for each of these directories, I use the same counter variable inside the for loop to name them:

Code:

export DIRECTORY"$COUNTER"=$PATHTOSUBDIR
The above code is executed before the line of code I am stuck on. I want to write an echo statement which will appear after the export statement, which will call the newly exported environment variable dynamically, in the same way I created the environment variable. Problem is, I'm stuck on syntax, single/double quotes and substitution syntax and I can't figure out how to do this. The line could look something like this:

Code:

echo $DIRECTORY$COUNTER
This way, if $COUNTER is set to 10 and I just exported DIRECTORY10, the echo statement will output the path stored in that variable each time the loop iterates. The above code is incorrect syntactically. The idea is to make this script dynamic, i.e. usable on folders with 1 or 1000 sub-folders, without having to hard-code the echo statement (the test).

Is there someone here who knows how I could write an echo statement that will correctly output the new environment variable for the current iteration of the for loop?

I hope this isn't too convoluted, its just a syntax question. Thanks in advance :)

Nominal Animal 02-18-2012 01:54 PM

Assuming you use KSH-93: Create a name reference variable, say
Code:

typeset -n nameref="DIRECTORY$COUNTER"
Then, using $nameref actually evaluates to the value in variable DIRECTORY$COUNTER (but with $COUNTER already evaluated at typeset time).

Did I understand your problem correctly?

bracken84 02-18-2012 03:23 PM

My goal is to echo the environment variable I export/create using the counter. Creating a reference variable is creating a new variable to echo, so this solution is not quite what I am looking for.

Code:

typeset -i COUNTER
let COUNTER=0
while [[ $COUNTER < $NUMDIRS ]] ; do
let COUNTER=$COUNTER+1
CHILDDIR=<series of commands to get the path>
echo $CHILDDIR
export DIR"$COUNTER"=$CHILDDIR
echo $DIR$COUNTER
done

It's that last line that does not evaluate correctly. For instance, if the loop creates/exports DIR324, I want the last line to output the contents of that same variable, $DIR324, to verify that the environment variable I created works. I do not want to create a new variable.

Maybe I'm making this harder than it needs to be, but I'm new to ksh scripting and I like to output my commands so as to evaluate how the data is being processed along the way. Once the script is done, I will go back and remove those echo(validation) lines.

# EDIT
As you can see, that last echo statement can not evaluate correctly ($DIR does not exist ANYWHERE in the script, its just what I want prefixed to $COUNTER to create the variable name, which takes the form $DIR#, in the export statement), but I don't want to call any other variable than the one that was just created.

Nominal Animal 02-18-2012 07:36 PM

Quote:

Originally Posted by bracken84 (Post 4606067)
Code:

export DIR"$COUNTER"=$CHILDDIR
verify that the environment variable I created works.

Code:

ksh -c "echo \"\$DIR$COUNTER\""
The current shell will first expand the above to ksh -c 'echo "$DIRcounter"' where counter is the value of $COUNTER in the current shell. (It does not use single quotes, but it does keep the third parameter as a single parameter; I added the single quotes to highlight that fact.)

The command will run another instance of the ksh shell. Only the environment variables (and not ksh variables) will be available to that instance. It will therefore echo the value of the DIRcounter environment variable (again, counter being whatever $COUNTER evaluated to in the parent shell).

bracken84 02-18-2012 11:30 PM

Awesome, that solves the problem. Thank you for the insight. :)

David the H. 02-19-2012 05:03 AM

This link is bash-based, but it includes some discussion of ksh.

http://mywiki.wooledge.org/BashFAQ/006

While perhaps not applicable in this specific case, most of the time you can, and should, avoid dynamic variable names, and use other techniques like arrays or functions instead.

bracken84 02-19-2012 11:43 AM

David,

First of all, thank you. I did some reading (including your link) and now my paths to sub-directories are stored in an array. I am successfully exporting the array values on each iteration of the loop and I am able to continue using Nominal Animal's ksh -c command to start a new shell and verify that the variables are available to child processes of the script.

I'm still fuzzy on why the $ and {} are not used in the export statement, however.

David the H. 02-20-2012 03:20 AM

Good to hear it. Arrays are one of the most useful, and most underused, tools in scripting. Of course not all shells support them, but the more powerful ones like bash and ksh do.

$ and ${} are only used when expanding a parameter; replacing the name with its content on the line. But the export command needs to know the name of the parameter to export, not the value it contains (although you can also give it a value at the same time).


As a side note, another situation where the $ is unneeded is when you use a variable in an arithmetic context.

Code:

$ x=4 y=3
$ echo "$(( x + y ))"
7

Since the only legal values in an arithmetic field are integers and operators, any other text string is assumed to be a variable containing a number, and is automatically expanded.

You can use the full form as well, of course. In fact, you still need to use the full form if you do any parameter substitutions on the values, or in other operations where the syntax would otherwise be ambiguous, such as concatenating variables.

Code:

$ x=4 y=3
$ echo "$(( xy + xy ))"
0
$ echo "$(( $x$y + $x$y ))"
86



All times are GMT -5. The time now is 05:43 PM.