i am trying to read the value of a bash variable defined earlier , but this variable name derived dynamically.
this is the bash script i am trying to do
$ mythreshold=10
$ table=my
$ threshold="$table"threshold
$ echo $("$threshold")
mythreshold
but when i try to read this variable value like
$ echo $("$threshold")
-bash: mythreshold: command not found
however i was expecting it to print
$ echo $("$threshold")
10
is there a way i can get this work, it should have printed the value of mythreshold variable defined above
$() is Command Substitution. It runs the command inside and returns the output. A variable name is not a command.
You can $(echo "$threshold") but that will only get the mythreshold back.
You need indirection for what you want. Specifically Evaluating indirect/reference variables.
As an example, for this specific case:
echo "${!threshold}"
Use eval command :
eval echo \${$threshold}
More details about this command can be found here:
eval command in Bash and its typical uses
Related
I've seen many examples where $USER and similar commands are used but I could never figure out what it meant.
Whenever I search $ on Google, it doesn't recognise the symbol.
it is used to access system variable.
for example:
if you type in linux and/or unix shell
...$ my_var="some value"
...$ echo my_var
will print "some value"
...$ echo $USER
will print the name of shell user
...$ echo $?
will print the result of the previous command when successfully will print 0
in other word the result of "exit (num)" of you shell.
"$" also can indicate you are logged as no-root user for some shells the root will be indicated "#"
The $ is a special character that tells the shell interpreter to interpret the contents following as a value for a variable. It is also called variable substitution.
In the case of commands or command output, it can be used to call a shell command and store it's output as a variable's value. For example:
VAR_1="$(ip link show)"
Calling the variable VAR_1 will print the output of the command ip link show.
This is called command substitution.
You can find out more information on special characters Here
as well as information on wildcards, keywords and more.
In bash from the CLI I can do:
$ ERR_TYPE=$"OVERLOAD"
$ echo $ERR_TYPE
OVERLOAD
$ read ${ERR_TYPE}_ERROR
1234
$ echo $OVERLOAD_ERROR
1234
This works great to set my variable name dynamically; in a script it doesn't work. I tried:
#!/bin/env bash
ERR_TYPE=("${ERR_TYPE[#]}" "OVERLOAD" "PANIC" "FATAL")
for i in "${ERR_TYPE[#]}"
do
sh -c $(echo ${i}_ERROR=$"1234")
done
echo $OVERLOAD_ERROR # output is blank
# I also tried these:
# ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # command not found
# read ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # it never terminates
How would I set a variable as I do from CLI, but in a script? thanks
When you use dynamic variables names instead of associative arrays, you really need to question your approach.
err_type=("OVERLOAD" "PANIC" "FATAL")
declare -A error
for type in "${err_type[#]}"; do
error[$type]=1234
done
Nevertheless, in bash you'd use declare:
declare "${i}_error=1234"
Your approach fails because you spawn a new shell, passing the command OVERLOAD_ERROR=1234, and then the shell exits. Your current shell is not affected at all.
Get out of the habit of using ALLCAPSVARNAMES. One day you'll write PATH=... and then wonder why your script is broken.
If the variable will hold a number, you can use let.
#!/bin/bash
ERR_TYPE=("OVERLOAD" "PANIC" "FATAL")
j=0
for i in "${ERR_TYPE[#]}"
do
let ${i}_ERROR=1000+j++
done
echo $OVERLOAD_ERROR
echo $PANIC_ERROR
echo $FATAL_ERROR
This outputs:
1000
1001
1002
I'd use eval.
I think this would be considered bad practice though (it had some thing to do with the fact that eval is "evil" because it allows bad input or something):
eval "${i}_ERROR=1234"
I added an alias:
$ alias anyalias="echo kallel"
If I execute:
$ anyalias
kallel
it executes the echo command without any problem.
Now, if I define a variable in this way:
$ var="anyalias"
and then execute with this way:
$ $var
-ash: anyalias: not found
Then I got a shell error.
How I can make $var running the command defined in the anyalias alias?
I m not looking to change the way of calling $var. But I m looking for a way of changing the definition of the alias or export it.
Instead of alias consider using function:
anyfunc() { echo "kallel"; }
v=anyfunc
$v
kallel
Safer is to store the call of function in an array (will store arguments also, if needed):
var=(anyfunc)
"${var[#]}"
kallel
That's because alias expansion is performed previous to parameter expansion:
Command-line Processing
As you can see, you can go through the process again with eval, which is not recommended.
Instead, you can use some alternatives as the one by #anubhava.
Example
$ alias anyalias="echo kallel"
$ var=anyalias
$ $var
bash: anyalias: command not found
$ eval $var
kallel
Again, use eval carefully. It's just to illustrate the expansion process.
I am new to shell scripting just started off.
I have written this script
#!/bin/sh
profile_type= cat /www/data/profile.conf
echo $profile_type
the o/p of this script is
. /tmp/S_panicA1.txt
. /tmp/S_panicA0.txt
away_Def="panicA1 panicA0"
away_Byp=0
away_Sts=$((panicA1+panicA0-away_Byp))
In this i want to get panicA1 panicA0 and 0 and store it in other variable how to do this?
When you want to assign the output of a command to a variable, you use the dollar parenthesis syntax.
foo=$(cat /my/file)
You can also use the backticks syntax.
foo=`cat /my/file`
In your script, you simply run the command cat and assign its result, nothing, to your variable. Hence the output consisting of the content of your file, result of cat, followed by an empty line, result of echo with an empty variable.
The colon command is a null command.
The : construct is also useful in the conditional setting of variables. For example,
: ${var:=value}
Without the :, the shell would try to evaluate $var as a command. <=???
I don't quite understand the last sentence in above statement. Can anyone give me some details?
Thank you
Try
var=badcommand
$var
you will get
bash: badcommand: command not found
Try
var=
${var:=badcommand}
and you will get the same.
The shell (e.g. bash) always tries to run the first word on each command line as a command, even after doing variable expansion.
The only exception to this is
var=value
which the shell treats specially.
The trick in the example you provide is that ${var:=value} works anywhere on a command line, e.g.
# set newvar to somevalue if it isn't already set
echo ${newvar:=somevalue}
# show that newvar has been set by the above command
echo $newvar
But we don't really even want to echo the value, so we want something better than
echo ${newvar:=somevalue}.
The : command lets us do the assignment without any other action.
I suppose what the man page writers meant was
: ${var:=value}
Can be used as a short cut instead of say
if [ -z "$var" ]; then
var=value
fi
${var} on its own executes the command stored in $var. Adding substitution parameters does not change this, so you use : to neutralize this.
Try this:
$ help :
:: :
Null command.
No effect; the command does nothing.
Exit Status:
Always succeeds.