I want to read variable name from txt file in bash script.
For example
I run var="thanks" in terminal
I create file.txt and txt file contains $var
I create variable var2 in terminal. var2=""
Then I run var2=$(<file.txt) command in terminal.
The Problem is
$ echo $var2
"$var"
I want the output of the echo $var command to be "thanks"
$ echo $var2
"thanks"
So what should I do?
If you put just var into the file without the $ and quotes, you can use variable indirection.
var2=$(< file.txt)
var2=${!var2}
echo $var2
Or, if you need the dollar sign and quotes, remove them using parameter expansion before applying the indirection
var2=$(< file.txt)
var2=${var2#'"$'}
var2=${var2%\"}
var2=${!var2}
echo $var2
${!var} indirect expansion:Anoter way for dropping $" if present:
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Tests:
var=Hello\ world\!
echo '"$var"' >file.txt
cat file.txt
"$var"
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!
echo 'var' >file.txt
cat file.txt
var
IFS='$"' read -a var2 <file.txt
var2=(${var2[*]})
echo ${!var2}
Hello world!
IFS Input Field Separator (usually contain: $' \t\n' <space><tab><newline>). All characters in this field are treated as field separator, so don't appear in array.
IFS='..' read .. when variable definition prepend command, variable are only affected for this execution
-a var2 read make var2 an array. Use declare -p to show his content:
IFS='$"' read -a var2 <file.txt
declare -p var2
declare -a var2=([0]="" [1]="" [2]="var")
${var2[*]} will merge var's fields in a single string, separated by 1st $IFS character.
echo "<${var2[*]}>"
< var>
var2=( foo bar baz ) will redefine var2 ignoring spaces (as any characters in $IFS)
var2=(${var2[*]}) # This step become useless, in 2nd case, but harmless.
declare -p var2
declare -a var2=([0]="var")
${!var2} is known as indirect expansion
echo ${!var2}
Hello world!
declare -n name=value make NAME a reference to the variable named by its value
IFS='$"' read -a var2 < file.txt
var2=(${var2[*]})
declare -p var2
declare -a var2=([0]="var")
declare -n var3=$var2
echo $var3
Hello world!
local -n in a function:readFrom() {
local var2
IFS='$"' read -a var2 < $1
var2=(${var2[*]})
local -n target=$var2
echo $target
}
Then
echo '"$var"' >file.txt
var=Hello\ world\!
readFrom file.txt
Hello world!
readFrom() {
local var2
IFS='$"' read -a var2 < $1
var2=(${var2[*]})
local -n target=$var2 result=${2:-INPUT}
result=("$target")
}
Then
readFrom file.txt newvar
echo "$newvar"
Hello world!
Advantage of this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With