This question already has answers here:
How can I reference a file for variables using Bash?
(9 answers)
Closed 2 years ago.
I want to use a variable initialized into a subscript, in order to avoid returning it with echo or return.
For example, my goal is to output $myvar with this script:
eval "./script.sh"
echo -n $myvar
declared inside script.sh like this:
declare -gx myvar # global and exported var
myvar=42
Output:
nothing
Is there another command or flag to add in replacement to declare -gx ? Or moving it before eval is the solution ?
You can use source instead of eval:
source "./script.sh"
Related
This question already has answers here:
Dynamic variable names in Bash
(19 answers)
How to use a variable's value as another variable's name in bash [duplicate]
(6 answers)
Closed 2 years ago.
I'm using gitlab-ci and i wanna package my artifact with specified VERSION which exported by previous stages, but the key of version value is generated with CI_COMMIT_SHORT_SHA, and i export it like this:
export COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION=${VERSION}
but i can't use it like
echo ${COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION}
or
`echo '$COMMIT_'"${CI_COMMIT_SHORT_SHA}"'_REVISION'`
any suggestions?
Hope below example help you:
$ foo=testvar
$ bar=testvalue
$ declare "someprefix_${foo}=${bar}"
# your variable
$ echo $someprefix_testvar
testvalue
# one way
$ eval echo '$'"someprefix_${foo}"
testvalue
# other way - prints the contents of the real variable
$ out="someprefix_${foo}"
$ echo ${!out}
testvalue
eval : Execute arguments as a shell command.
declare : declare is a bash built-in command that allows you to update attributes applied to variables within the scope of your shell.
Refer : http://mywiki.wooledge.org/BashFAQ/006#Indirection
You need:
$ declare "COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION=${VERSION}"
$ out="COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION"
$ echo ${!out}
Test Results:
[akshay#db1 tmp]$ CI_COMMIT_SHORT_SHA=abcdef
[akshay#db1 tmp]$ VERSION=1.2.0
[akshay#db1 tmp]$ declare "COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION=${VERSION}"
[akshay#db1 tmp]$ out="COMMIT_${CI_COMMIT_SHORT_SHA}_VERSION"
[akshay#db1 tmp]$ echo ${!out}
1.2.0
This question already has answers here:
Brace expansion with a Bash variable - {0..$foo}
(5 answers)
Closed 3 years ago.
I am trying to use command line arguments for arithmetic but cant seem to find any documentation explaining how to do this. As an example if I use:
for i in {$1..$2}
do
echo $i
done
and call
test.sh 1 20
the following output is produced:
{1..20}
instead of
1
2
3
..
20
The following will also work:
declare -a ary='({'$1..$2'})'
for i in "${ary[#]}"; do
echo "$i"
done
Note that declare is as harmful as eval.
You need to check and sanitize the arguments before use.
There's no way to do this properly without the evil eval() with brace expansion in bash.
You can use seq instead :
for i in $(seq $1 $2); do
This question already has answers here:
Use the result of a shell command in a conditional in a makefile
(1 answer)
How to use Bash parameter substitution in a Makefile?
(1 answer)
Closed 4 years ago.
I have next rule in Makefile:
dbrestoretable:
echo ${TABLE:-asdf}
When I run:
$ make dbrestoretable
echo
But:
$ echo ${TABLE:-asdf}
asdf
Why default value asdf is not echoed in first case?
UPD
Specified duplicate speaks about how to use variable assigned in Makefile. And it does not answer why default value is not used
Look at this modified example:
dbrestoretable:
echo ${TABLE:-asdf}
echo ${TABLE}
Then run:
$ make dbrestoretable TABLE=mytable
echo
echo mytable
$ make dbrestoretable
echo
echo
As you can see when I use ${TABLE:-asdf} it just return empty string. But I expect in first run mytable and second run asdf value to be echoed
This question already has answers here:
Dynamic variable names in Bash
(19 answers)
What is indirect expansion? What does ${!var*} mean?
(6 answers)
Lookup shell variables by name, indirectly [duplicate]
(5 answers)
Closed 5 years ago.
Say I have two variables;
var_one_string=foo
var_two_string=bar
How would I accomplish something like this (pseudo code examples);
EXAMPLE 1
for i in one two; do
echo $var_${i}_string
done
# Desired output
foo
bar
EXAMPLE 2
for i in one two; do
echo $var_$(echo ${i})_string
done
# Desired output
foo
bar
I understand that this is bad substitution, I am just wondering if there is a way to nest a string within another variable call?
EDIT: I was able to get it to work
var_one_string=foo
var_two_string=bar
for i in $(echo ${!var_*}); do
echo ${!i}
done
foo
bar
Use the declare built-in along with indirect-variable expansion in bash. First define the elements of for the dynamic nature in an array as
#!/bin/bash
list=(one two)
unset count
for var in "${list[#]}"; do
declare var_${var}_string="string"$((++count))
done
and now access the created variables using indirect expansion
for var in "${list[#]}"; do
dymv="var_${var}_string"
echo "${!dymv}"
done
and never use eval for this requirement. Could be dangerous because of unlikely code-injection possibility with a harmful command.
Basically, you can use eval: echo $(eval '$var_'"${i}")
But you can also use a dictionnary:
declare -A vars
vars=( ["one"]="number-one" ["two"]="number-two" )
i="one"
echo "${vars[${i}]}"
This question already has answers here:
Why can't I specify an environment variable and echo it in the same command line?
(9 answers)
Closed 7 years ago.
In bash, I can pass an environment variable to a single command in the following way:
KEY=VAL <command>
However, I don't understand why the following doesn't work:
KEY=VAL echo $KEY
While this works:
KEY=VAL bash -c 'echo $KEY'
i.e. the first one prints a blank line while the other prints "VAL". I'd expect both to print "VAL".
Because KEY=VAL echo $KEY isn't having echo expand the $KEY variable.
The current shell is doing that before it runs echo (or whatever).