I have my parameters stored in a file and calling them with a prefix which i get it has input. now, i am getting the input and prefixing it and storing as a new variable and then pointing my new variable indirectly to my actual variable to use in my script.
Is there a way to directly mention the indirect variable pointer to my main variable like value1=$(!$pk_value1) something like this, so that i can skip the new variable declaration. i have close to 10 variables to be declared which makes my code lengthy.
My current code :
source values.sh read -p "Enter Identifier : " pk value1here=${pk}_value1 value2here=${pk}_value2 value3here=${pk}_value3 value1=${!value1here} value2=${!value2here} value3=${!value3here}
values.sh (I have close to 300 variables declared here)
p1_value1=name1 p1_value2=host1 p1_value3=user1 p2_value1=name2 p2_value2=host2 p2_value3=user2
Is there a way to directly mention the indirect variable pointer + my name like value1=$(!$pk_value1) something like this, so that i can skip the new variable declaration. i have close to 10 variables to be declared which makes my code lengthy.
Advertisement
Answer
If your Bash is recent enough, then use the -n
indirect variable attribute like this:
#!/usr/bin/env bash source values.sh read -r -p 'Enter Identifier : ' pk declare -n value1="${pk}_value1" value2="${pk}_value2" value3="${pk}_value3"
Alternate method with populating an associative array from the file values.sh
:
#!/usr/bin/env bash declare -A values="($( xargs -l1 bash -c 'IFS="=" read -r k v <<<"$@"; printf "[%q]=%qn" "$k" "$v"' _ <values.sh ))" read -r -p 'Enter Identifier : ' pk declare -- value1="${values[${pk}_value1]}" value2="${values[${pk}_value2]}" value3="${values[${pk}_value3]}"
Working of the Associative array population:
xargs -l1
will translate the stdio
input stream’s lines (here: <values.sh
) into arguments to a command.
The command called by xargs
is bash -c
, witch executes an inline script detailed here:
# Read variables k and v from the arguments # streamed as a here-string <<<"", # using the = sign as the Internal Field Separator. # Actually splitting key=value into k and v. IFS="=" read -r k v <<<"$@" # Format variables k and v into an Associative array # entry declaration in the form [key]=value, # with %q adding quotes or escaping if required. printf "[%q]=%qn" "$k" "$v"
Finally the Associative array declaration and assignment declare -A values="($(commands))"
gets the entries generated by the xarg
and inline shell script commands
.