Using variable as part of another variable name - bash

I'm trying to use a variable as part of another variable's name.
For example, I have some variables in a CONFIG_ scope.
echo $CONFIG_systema_value > "testconfig"
echo $CONFIG_systemb_value > "testconfig2"
and then I have a "deciding" variable like WANTEDSYSTEM
echo $WANTEDSYSTEM > "systema"
I need to be able to "dynamically" switch the config depending on the wantedsystem variable.
My initial attempts I tried something like this echo $CONFIG_$WANTEDSYSTEM_value which I would like to have output testconfig as if I was asking it to echo $CONFIG_systema_value

You can use the ${!name} syntax to indirectly reference a variable, like this:
CONFIG_systema_value=foo
CONFIG_systemb_value=bar
WANTEDSYSTEM=systema
target_var_name="CONFIG_${WANTEDSYSTEM}_value"
echo ${!target_var_name}
(Note that this is bash-specific syntax, but it sounds like that's what you're looking for.)

Related

Variation on a Variable Variable in Bash

I am looking for a way to add a string to a variable name in bash and evaluate this as a new variable. Example:
#!/bin/bash
file="filename"
declare ${file}_info="about a file"
declare ${file}_status="status of file"
declare ${file}_number="29083451"
echo ${${file}_info} # <-- This fails with error: "bad substitution"
Is there a way to do this?
I'm not actually implementing this in any production code anywhere. I just want to know if there is some way to create a variable name using a variable and a string. It seemed like an interesting problem.
Also note that I am not asking about bash indirection, which is the use of ${!x} to evaluate the contents of a variable as a variable.
You aren't asking about indirection, but that's what can help you:
info=$file\_info
echo ${!info}

Storing bash output into a variable using eval

I have a line of code
eval echo \$$var
which prints a string. How can I store this string into a variable?
Like this:
eval c=\$$var
a better, safer way is to use indirection:
c=${!var}
newVariable=$(eval echo \$$var)
You can try this: It worked for me on bash.
c=$(eval echo \${$var})
Example: If HOME is the environment variable that contains your home directory like /export/users/john, then embedding a variable within another variable and then unpacking that combination would work like this:
var=HOME
c=$(eval echo \${$var})
echo $c
/export/users/john
While this might look unnecessarily convoluted it will be useful in certain scenarios.
This can achieved by using the back quote syntax : ` `
c=`$var`

how to access an automatically named variable in a Bash shell script

I have some code that creates a variable of some name automatically and assigns some value to it. The code is something like the following:
myVariableName="zappo"
eval "${myVariableName}=zappo_value"
How would I access the value of this variable using the automatically generated name of the variable? So, I'm looking for some code a bit like the following (but working):
eval "echo ${${myVariableName}}"
(... which may be used in something such as myVariableValue="$(eval "echo ${${myVariableName}}")"...).
Thanks muchly for any assistance
If you think this approach is madness and want offer more general advice, the general idea I'm working on is having variables defined in functions in a library with such names as ${usage} and ${prerequisiteFunctions}. These variables that are defined within functions would be accessed by an interrogation function that can, for instance, ensure that prerequisites etc. are installed. So a loop within this interrogation function is something like this:
for currentFunction in ${functionList}; do
echo "function: ${currentFunction}"
${currentFunction} -interrogate # (This puts the function variables into memory.)
currentInterrogationVariables="${interrogationVariables}" # The variable interrogationVariables contains a list of all function variables available for interrogation.
for currentInterrogationVariable in ${currentInterrogationVariables}; do
echo "content of ${currentInterrogationVariable}:"
eval "echo ${${currentInterrogationVariable}}"
done
done
Thanks again for any ideas!
IIRC, indirection in bash is by !, so try ${!myVariableName}
Try:
echo ${!myVariableName}
It will echo the variable who's name is contained in $myVariableName
For example:
#!/bin/bash
VAR1="ONE"
VAR2="TWO"
VARx="VAR1"
echo ${VARx} # prints "VAR1"
echo ${!VARx} # prints "ONE"

Strange shell behaviour

Here is a simple bash script:
a="asd"
b="qf"
echo "$a.$b"
echo "$a_$b"
It's output is:
asd.qf
qf
Why the second line is not "asd_qf" but "qf"?
Because you haven't defined a variable named a_. For that second printout to work, use:
echo "${a}_$b"
Your second echo displays the value of variable $a_ which is unset.
Use echo "${a}_$b"
The shell has rules about what can go in a variable name, and $a_ is interpreted as the variable named a_ (there is no variable with that name so its value is empty).
You can always add braces to be explicit. In this case, ${a}_$b will clearly identify what the variable name is and the result will be what you expect.

Multi layer variable substitution in shell.. possible?

I have multiple variables in a shell script; i was trying to save some code duplication and wanted to do something like following
# variables
FLAG=SIM
SIM_ICR_KEY_VAL="http://www.example.com/simi/icr"
REAL_ICR_KEY_VAL="http://www.example.com/real"
Based on the FLAG value i want to access the correct variable (without using IF's)
When i try this it echos the variable name & not the value itself.
echo $(echo ${FLAG}_ICR_KEY_VAL)
On further note; i need to use these substitutions inline in a sed statememt:
sed "s!${ISTR_KEY}=.*!${ISTR_KEY}=${SIM_ISTR_KEY_VAL}!" > tmp.file
... i am not sure its possible or not, please suggest
Reflection can be achieved with the infamous eval:
eval thisvar=\$${FLAG}_INC_KEY_VAL;
echo "We are using $thisvar"
Whenever you find yourself dynamically synthesizing a variable name, though, you are probably Doing It Wrong. You should consider alternatives like arrays:
ICR_KEY_VAL[0]="http://www.example.com/simi/icr"
ICR_KEY_VAL[1]="http://www.example.com/real"
SIM=0
echo ${ICR_KEY_VAL[$SIM]}
I don't know how to do it directly, but in bash you can do it indirectly:
FLAG=SIM
SIM_ICR_KEY_VAL="http://www.example.com/simi/icr"
REAL_ICR_KEY_VAL="http://www.example.com/real"
FLAG_ICR_KEY_VAL=${FLAG}_ICR_KEY_VAL
sed "s!${ISTR_KEY}=.*!${ISTR_KEY}=${!FLAG_ISTR_KEY_VAL}!" > tmp.file

Resources