Bash - When to use '$' in front of variables? - bash

I'm very new to bash scripting, and as I've been searching for information online I've found a lot of seemingly contradictory advice. The thing I'm most confused about is the $ in front of variable names. My main question is, when is and isn't it appropriate to use that syntax? Thanks!

Basically, it is used when referring to the variable, but not when defining it.
When you define a variable you do not use it:
value=233
You have to use them when you call the variable:
echo "$value"
There are some exceptions to this basic rule. For example in math expresions, as etarion comments.
one more question: if I declare an array my_array and iterate through
it with a counter i, would the call to that have to be $my_array[$i]?
See the example:
$ myarray=("one" "two" "three")
$ echo ${myarray[1]} #note that the first index is 0
two
To iterate through it, this code makes it:
for item in "${myarray[#]}"
do
echo $item
done
In our case:
$ for item in "${myarray[#]}"; do echo $item; done
one
two
three

I am no bash user that knows too much. But whenever you declare variable you would not use the $, and whenever you want to call upon that variable and use its value you would use the $ sign.

Related

Using a variable for associative array key in Bash

I'm trying to create associative arrays based on variables. So below is a super simplified version of what I'm trying to do (the ls command is not really what I want, just used here for illustrative purposes)...
I have a statically defined array (text-a,text-b). I then want to iterate through that array, and create associative arrays with those names and _AA appended to them (so associative arrays called text-a_AA and text-b_AA).
I don't really need the _AA appended, but was thinking it might be
necessary to avoid duplicate names since $NAME is already being used
in the loop.
I will need those defined and will be referencing them in later parts of the script, and not just within the for loop seen below where I'm trying to define them... I want to later, for example, be able to reference text-a_AA[NUM] (again, using variables for the text-a_AA part). Clearly what I have below doesn't work... and from what I can tell, I need to be using namerefs? I've tried to get the syntax right, and just can't seem to figure it out... any help would be greatly appreciated!
#!/usr/bin/env bash
NAMES=('text-a' 'text-b')
for NAME in "${NAMES[#]}"
do
NAME_AA="${NAME}_AA"
$NAME_AA[NUM]=$(cat $NAME | wc -l)
done
for NAME in "${NAMES[#]}"
do
echo "max: ${$NAME_AA[NUM]}"
done
You may want to use "NUM" as the name of the associative array and file name as the key. Then you can rewrite your code as:
NUM[${NAME}_AA]=$(wc -l < "$NAME")
Then rephrase your loop as:
for NAME in "${NAMES[#]}"
do
echo "max: ${NUM[${NAME}_AA]}"
done
Check your script at shellcheck.net
As an aside: all uppercase is not a good practice for naming normal shell variables. You may want to take a look at:
Correct Bash and shell script variable capitalization

Including Variables in Strings, Bash Scripting

I need to insert variables into a string to create a URL. Right now, I'm looping over an array of values and inserting them into the string.
year="2015"
for i in "${array[#]}"
do
url="https://www.my-website.com/place/PdfLinkServlet?file=\place\\$i\099%2Bno-display\\$year_$i.pdf"
echo $url
done
The $i is being replaced with the corresponding array element, but $year just leaves a blank space. Can someone explain why and how to get a url that looks like: url="https://www.my-website.com/place/PdfLinkServlet?file=\place\place_id\099%2Bno-display\2015_place_id.pdf"
Because variable names can legally contain _ characters, there's no way for Bash to know that you wanted $year instead of $year_. To disambiguate, you can use enclose the variable name in brackets like this:
${year}_${i}.pdf
It's not bad practise to do this any time you are shoving variable expansions together. As you can see, it actually makes them stand out better to human eyes too.
Use ${var} instead:
year="2015"
for i in "${array[#]}"; do
url="https://www.my-website.com/place/PdfLinkServlet?file=place${i}099%2Bno-display${year}_${i}.pdf"
echo "$url"
done
Here is a little hack that also works well. And I use it for my projects frequently. Add the _ to the end of 2015 in the variable year
like year="2015_"
and remove the _ from the url variable and join the two variables i and year together like $year$i
I added an arbitrary array so that the script can run.
#!/bin/bash
year="2015_"
array=(web03 web04 web05 web06 web07)
for i in "${array[#]}";
do
url="https://www.my-website.com/place/PdfLinkServlet?file=\place\\$i\099%2Bno-display\\$year$i.pdf"
echo $url
done

concatenate variables in a bash script

Hi I would like to set a variable by concatenating two other variables.
Example
A=1
B=2
12=C
echo $A$B
desired result being C
however the answer I get is always 12
Is it possible?
UPDATED
Example
A=X
B=Y
D=$A$B
xy=test
echo $D
desired result being "test"
It looks like you want indirect variable references.
BASH allows you to expand a parameter indirectly -- that is, one variable may contain the name of another variable:
# Bash
realvariable=contents
ref=realvariable
echo "${!ref}" # prints the contents of the real variable
But as Pieter21 indicates in his comment 12 is not a valid variable name.
Since 12 is not a valid variable name, here's an example with string variables:
> a='hello'
> b='world'
> declare my_$a_$b='my string'
> echo $my_hello_world
my string
What you are trying to do is (almost) called indirection: http://wiki.bash-hackers.org/syntax/pe#indirection
...I did some quick tests, but it does not seem logical to do this without a third variable - you cannot do concatenated indirection directly as the variables/parts being concatenated do not evaluate to the result on their own - you would have to do another evaluation. I think concatenating them first might be the easiest. That said, there is a chance you could rethink what you're doing.
Oh, and you cannot use numbers (alone or as the starting character) for variable names.
Here we go:
cake="cheese"
var1="ca"
var2="ke"
# this does not work as the indirection sees "ca" and "ke", not "cake". No output.
echo ${!var1}${!var2}
# there might be some other ways of tricking it to do this, but they don't look to sensible as indirection probably needs to work on a real variable.
# ...this works, though:
var3=${var1}${var2}
echo ${!var3}

how to access an automatically named variable in a Bash shell script

I have some code that creates a variable of some name automatically and assigns some value to it. The code is something like the following:
myVariableName="zappo"
eval "${myVariableName}=zappo_value"
How would I access the value of this variable using the automatically generated name of the variable? So, I'm looking for some code a bit like the following (but working):
eval "echo ${${myVariableName}}"
(... which may be used in something such as myVariableValue="$(eval "echo ${${myVariableName}}")"...).
Thanks muchly for any assistance
If you think this approach is madness and want offer more general advice, the general idea I'm working on is having variables defined in functions in a library with such names as ${usage} and ${prerequisiteFunctions}. These variables that are defined within functions would be accessed by an interrogation function that can, for instance, ensure that prerequisites etc. are installed. So a loop within this interrogation function is something like this:
for currentFunction in ${functionList}; do
echo "function: ${currentFunction}"
${currentFunction} -interrogate # (This puts the function variables into memory.)
currentInterrogationVariables="${interrogationVariables}" # The variable interrogationVariables contains a list of all function variables available for interrogation.
for currentInterrogationVariable in ${currentInterrogationVariables}; do
echo "content of ${currentInterrogationVariable}:"
eval "echo ${${currentInterrogationVariable}}"
done
done
Thanks again for any ideas!
IIRC, indirection in bash is by !, so try ${!myVariableName}
Try:
echo ${!myVariableName}
It will echo the variable who's name is contained in $myVariableName
For example:
#!/bin/bash
VAR1="ONE"
VAR2="TWO"
VARx="VAR1"
echo ${VARx} # prints "VAR1"
echo ${!VARx} # prints "ONE"

Shell script variable problem

I'm trying to write a shell script to automate a job for me. But i'm currently stuck.
Here's the problem :
I have a variable named var1 (a decreasing number from 25 to 0
and another variable named
var${var1} and this equals to some string.
then when i try to call var${var1} in anywhere in script via echo it fails.
I have tried $[var$var1], ${var$var} and many others but everytime it fails and gives the value of var1 or says operand expected error.
Thanks for your help
It's probably better if you use an array, but you can use indirection:
var25="some string"
var1=25
indirect_var="var$var1"
echo ${!indirect_var} # echoes "some string"
There's only one round of variable expansion, so you can't do it directly. You could use eval:
eval echo \${var$var1}
A better solution is to use an array:
i=5
var[$i]='foo'
echo ${var[$i]}
It sounds like you need bash variable indirection. Take a look at the link below.
http://mywiki.wooledge.org/BashFAQ/006

Resources