Expand a variable within variable right before echo - bash

Example:
testing="test"
var="\"${testing} the variable\""
testing="Update"
echo "$var"
Output:
test the variable
Required output:
Update the variable

Variables are expanded when the string is used, they're not templates that remember the variable substitution.
If you need to do this, you need to put the variable literally into the string, and use eval.
testing="test"
var='"${testing} the variable"'
testing="Update"
eval "echo $var"
But eval is dangerous -- it will execute any shell commands in the string. A better solution would probably be to use some kind of placeholder string and replace it using the shell expansion operator.
var='#testing# the variable'
testing="Update"
echo "${var//#testing#/$testing}"

Related

Assign ASCII values to variable in shell

I'm still new at shell scripting
I want to assign * to a variable an print it. Write now I'm just printing it with:
echo -e "\052"
Is there a way to assign that value to a variable?
Use $(cmd) or `cmd` to capture a command's output. The $(...) form is preferred because it's easier to nest.
var=$(echo -e "\052")
The shell will interpret escape sequences inside $'...'. That's single quotes with a dollar sign in front.
var=$'\052'
Or of course you could write the asterisk directly. Quote it to prevent wildcard expansion.
var='*'
When you print it, make sure to quote the variable. It's annoying to always have to type double quotes any time you use a variable, but it's usually the right thing to do.
echo "$var" # yes
echo $var # no
Using backticks, ``, allows you to capture the output of a command. Many shells have a more sophisticated syntax, $(). But backticks are the most portable.
var=`echo -e "\052"`

Get keys of an array with variable name in bash

In my bash script I have two arrays. Depending on some logic either one or another shall be used, so I'm getting the name of a required array in a variable varName. I can surely get the values of this array with the code below but is there a way to get it's keys? Tried several options but no luck.
declare -A foo=([a]=b [c]=d)
declare -A bar=([e]=f [g]=h)
varName=foo
varArray=$varName[#]
echo ${!varArray}
Thanks.
Not without resorting to eval, unfortunately. To be safe, make sure varName is just a single valid identifier.
[[ varName =~ ^[a-zA-Z_][a-zA-Z_0-9]+$ ]] && eval "echo \${!$varName[#]}"
eval is necessary to provide a second round of parsing and evaluation. In the first round, the shell performs the usual parameter expansion, resulting in the string echo ${!foo[#]} being passed as the single argument to eval. (In particular, the first dollar sign was escaped and so is passed literally; $varName is expanded to foo; and the quotes are removed as part of quote removal. eval then parses that string and evaluates it.
$ eval "echo \${!$varName[#]}"
# echo ${!foo [#]}
# The above is the argument that `eval` sees, after the shell
# does the normal evaluation before calling `eval`. Parameter
# expansion replaces $varName with foo and quote removal gets
# rid of the backslash before `$` and the double quotes.
a c
If you are using bash 4.3 or later, you can use a nameref.
declare -n varName=foo
for key in "${!varName[#]}"; do
echo "$key"
done
There is an IFS-safe method to get the keys (or values) of an array indirectly:
declare -a things=("an apple" "a banana")
declare -a tmp
arrayName=things
eval "tmp=(\"\${$arrayName[#]}\")"
# "${tmp[#]}" is now ("an apple" "a banana")

How to use a variable's value as another variable's name in bash [duplicate]

This question already has answers here:
Dynamic variable names in Bash
(19 answers)
Closed 6 years ago.
I want to declare a variable, the name of which comes from the value of another variable, and I wrote the following piece of code:
a="bbb"
$a="ccc"
but it didn't work. What's the right way to get this job done?
eval is used for this, but if you do it naively, there are going to be nasty escaping issues. This sort of thing is generally safe:
name_of_variable=abc
eval $name_of_variable="simpleword" # abc set to simpleword
This breaks:
eval $name_of_variable="word splitting occurs"
The fix:
eval $name_of_variable="\"word splitting occurs\"" # not anymore
The ultimate fix: put the text you want to assign into a variable. Let's call it safevariable. Then you can do this:
eval $name_of_variable=\$safevariable # note escaped dollar sign
Escaping the dollar sign solves all escape issues. The dollar sign survives verbatim into the eval function, which will effectively perform this:
eval 'abc=$safevariable' # dollar sign now comes to life inside eval!
And of course this assignment is immune to everything. safevariable can contain *, spaces, $, etc. (The caveat being that we're assuming name_of_variable contains nothing but a valid variable name, and one we are free to use: not something special.)
You can use declare and !, like this:
John="nice guy"
programmer=John
echo ${!programmer} # echos nice guy
Second example:
programmer=Ines
declare $programmer="nice gal"
echo $Ines # echos nice gal
This might work for you:
foo=bar
declare $foo=baz
echo $bar
baz
or this:
foo=bar
read $foo <<<"baz"
echo $bar
baz
You could make use of eval for this.
Example:
$ a="bbb"
$ eval $a="ccc"
$ echo $bbb
ccc
Hope this helps!
If you want to get the value of the variable instead of setting it you can do this
var_name1="var_name2"
var_name2=value_you_want
eval temp_var=\$$var_name1
echo "$temp_var"
You can read about it here indirect references.
You can assign a value to a variable using simple assignment using a value from another variable like so:
#!/usr/bin/bash
#variable one
a="one"
echo "Variable a is $a"
#variable two with a's variable
b="$a"
echo "Variable b is $b"
#change a
a="two"
echo "Variable a is $a"
echo "Variable b is $b"
The output of that is this:
Variable a is one
Variable b is one
Variable a is two
Variable b is one
So just be sure to assign it like this b="$a" and you should be good.

what's the difference of echoing the variables in this way?

What is the difference of echoing these variable in bash scripting?
EXAMPLE:
I declare a variable
VARIABLE="Hello World"
echo $VARIABLE
What's the difference between the one above and this below?
echo ${VARIABLE}
Does it make a difference if I put {} or not?
No difference in your code
The curly braces, To delimiting a variable name are used for parameter expansion so you can do things like
Truncate a variable' content
$ var="abcde"; echo ${var%e*}
abcd
Make substitutions similar to sed
$ var="abcde"; echo ${var/e/1}
abcd1
Braces can also be useful when the expansion occurs in certain contexts. For example:
FOO=bar
echo $FOO1 # tries to print the value of a variable named "FOO1"
echo ${FOO}1 # prints "bar1"

How to echo a variable containing an unescaped dollar sign in bash

If I have a variable containing an unescaped dollar sign, is there any way I can echo the entire contents of the variable?
For example something calls a script:
./script.sh "test1$test2"
and then if I want to use the parameter it gets "truncated" like so:
echo ${1}
test1
Of course single-quoting the varaible name doesn't help. I can't figure out how to quote it so that I can at least escape the dollar sign myself once the script recieves the parameter.
The problem is that script receives "test1" in the first place and it cannot possibly know that there was a reference to an empty (undeclared) variable. You have to escape the $ before passing it to the script, like this:
./script.sh "test1\$test2"
Or use single quotes ' like this:
./script.sh 'test1$test2'
In which case bash will not expand variables from that parameter string.
The variable is replaced before the script is run.
./script.sh 'test1$test2'
by using single quotes , meta characters like $ will retain its literal value. If double quotes are used, variable names will get interpolated.
As Ignacio told you, the variable is replaced, so your scripts gets ./script.sh test1 as values for $0 and $1.
But even in the case you had used literal quotes to pass the argument, you shoudl always quote "$1" in your echo "${1}". This is a good practice.

Resources