2) Variables & Shell Expansions
Last updated
Was this helpful?
Last updated
Was this helpful?
Variables allow us to store useful data under convenient names Shell Expansions are very powerful features that allow us to retrieve data, ie to get data back out of our variables, process command output and perform calculations.
A parameter is any entity that stores values
Shell parameters are used to store and reference useful data that can be used repeatedly in our scripts. There are 3 types of shell parameters:
Variables - a parameter whose values can be manually changed.
User Defined Variables - All user defined variable names is in lower case and the = (equal sign) does NOT have any spaces between it. Just remember the equal sign is not = to something, all it means is that the variable name corresponds to the value given it. For example:
#! /bin/bash
name="Sarah"
To print the script to the screen, we use the "echo" command and we retrieve the variable value using the ${parameter}
This is called parameter expansion
echo "Hello ${name}"
Shell Defined Variables (Environment Variables) -
Bourne Shell Variables - original shell by Stephen Bourne -
BASH Shell Variables - based on the Bourne Shell -
Because the Bourne and Bash shells are similar we get system variables that work on both, however because BASH has continued to be developed, some of the variables are specific to BASH alone and these are called BASH SHELL VARIABLES
Positional Parameters
Special Parameters
echo ${PATH}
Bash Shell Variable echo ${PATH}- note that officially we normally incorporate { } curly brackets when we call it (or parameter expansion) , however we can use it without them if we do a really simple parameter expansion such as echo $PATH. Get into the habit of using { } for parameter expansion of variables
echo ${HOME}
echo ${USER} These two above refer to the CURRENT user that's logged in. In my case I get the following:
echo $HOSTNAME
echo $HOSTTYPE These two refer to the details of the architecture and hostname of the computer/server that they are administering
echo $PS1 This refers to the "prompt string 1" which is the prompt that we see at the beginning of our shell prompt in the terminal
We can change the prompt if we want by assigning PS1 a new variable. Remember this wont survive a reboot. For example: PS1="#: "
All shell variables have UPPERCASE names that's why we need to keep our user variables as all LOWERCASE
If you have upper and lowercase in string, and we want to reference it all as lower case such as if we get user input that could contain both formats, we want to use that input as a variable - we need to make sure its ALL in lowercase OR all in uppercase:
We can also start at the other end , in this case we use negative numbers and because we cant have negative 0, we start at -1
If we don't stipulate the 'length', Bash assumes that the entire length is required starting from the offset. For example, from the above scenario, we stipulated
echo ${numbers:4}
we would get the output
6789
command substitution is that it used to directly reference the RESULT of a command using normal parenthesis $(command)
Similar to shell parameter expansion.
With parameter expansion a variable like name=Dave
, echo "Hello ${name}"
the complete section ${name}
is replaced by the value name which is in this case Dave.
The difference with command substitution is that it used to directly reference the RESULT of a command using normal parenthesis $(command)
For example we can look at the date command:
Shell expansions so far:
Parameter expansion ${parameter}
Command substitution $(command)
Arithmetic expansion $((expression))
+ - / * = Mathematical Operators and the numbers they operate on are called the Operands
Don't forget PEMDAS(Parentheses, Exponents, Multiplication and Division[left to right], Addition and Subtraction[left to right]) when it comes to figuring which to do first :) PEMDASLR - (LR=Left to Right)
The binding of the operator determines the order or computations performed by some operators with equal priority, put side by side in one expression. BASH has left-sided binding, which means that the calculation of expressions is handled from left to right
We need to note that arithmetic expansion CANNOT manage decimal numbers !!
We will use | bc (basic calculator) later to handle decimal numbers
Tilde expansion can do more than expand home directories, we can use it to provide convenient shortcuts to directories we have already visited.
Your current directory is always stored internally within a shell variable $PWD
(print working directory)
If I echo $PWD
I will get /home/ubuntu
Now, let me change my pwd to /etc/ -->
$cd /etc/
and do a echo $PWD I will get /etc
Bash keeps track of your previous directory in a shell variable called $OLDPWD, which in this case was /home/ubuntu
This is good if you need to pop back and from an existing directory when performing an installation script
Instead for typing out the $OLDPWD and $PWD, there is a shortcut: We can use tilde plus , or tilde minus ~+ or ~- To get to the $OLDPWD we use ~- and to check the $PWD we use ~+
There are 2 types of lists that you can expand to within your braces:
STRING LISTS can contain ANY set of individual character or words and can be useful for expanding out months of the year or a set of usernames. For example
echo {a,19,z,barry,42}
----->NO UNQUOTED SPACES BETWEEN COMMAS!!
a 19 z barry 42
- This has been expanded out to this
RANGE LISTS are useful for expanding out SEQUENCES of characters that FOLLOW a particular order for example numbers from 1 to 100 or from A-Z. Range list loses some of their flexibility that string lists have because string lists can contain ANY value, but because each value in a range list does not need to by typed manually, range lists make up for this lack of flexibility with their increased ease of use and extensibility.
echo {1..10}
- we use 2 dots and no spaces around the double dots
1 2 3 4 5 6 7 8 9 10
echo {10..1}
10 9 8 7 6 5 4 3 2 1
If we wanted to have steps between numbers, say 2-50 in steps of 2,
echo {2..50..2}
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50
Brace expansion allows you to add fixed pieces of text to the beginning and end of each element of the expansion - prefix and postfix
$ cd ~/bash_course/
$ mkdir journal
$ cd journal
"Best to test out using the echo command before writing a script in case anything goes wrong :)
echo month_{1..12}
---> what this does is that "month will be prefixed to each folder month_1 month_2 etc
OK - so echo command works, so lets now create the folders within the journal directory
mkdir ~/bashcourse/journal/month{01..12}
ls -la ---> we can see all folders in there
Next, we want to create 31 .txt files in each folder
Niw we want add in each folder 32 .txt files for each day
touch month_{01..12}/day_{01..31}.txt
ls -la ~/bash_course/journal/month_03/
We can change it back again by running # source ~/.bashrc If you want it to be permanent then edit the .bashrc file. We can generate our own if we want using