For those of you that have dabbled in programming before, you’ll be quite familiar with variables. For those of you that haven’t, think of a variable as a temporary store for a simple piece of information. These variables can be very useful for allowing us to manage and control the actions of our Bash Scripts. Today we’ll go through a variety of different ways that variables have their data set and ways we can then use them.
Variables are one of those things that are actually quite easy to use but are also quite easy to get yourself into trouble with if you don’t properly understand how they work. As such there is a bit of reading in this tutorial but if you take the time to go through and understand it you will be thankful you did later on when we start dabbling in more complex scripts.
How Variables Work
A variable is a temporary store for a piece of information. There are two actions we may perform for variables:
- Setting a value for a variable.
- Reading the value for a variable.
Variables may have their value set in a few different ways. The most common are to set the value directly and for its value to be set as the result of processing by a command or program. You will see examples of both below.
To read the variable we then place its name (preceded by a $ sign) anywhere in the script we would like. Before Bash interprets (or runs) every line of our script it first checks to see if any variable names are present. For every variable it has identified, it replaces the variable name with its value. Then it runs that line of code and begins the process again on the next line.
Here are a few quick points on syntax. They will be elaborated on and demonstrated as we go into more detail below.
- When referring to or reading a variable we place a $ sign before the variable name.
- When setting a variable we leave out the $ sign.
- Some people like to always write variable names in uppercase so they stand out. It’s your preference however. They can be all uppercase, all lowercase, or a mixture.
- A variable may be placed anywhere in a script (or on the command line for that matter) and, when run, Bash will replace it with the value of the variable. This is made possible as the substitution is done before the command is run.
Command Line Arguments
Command line arguments are commonly used and easy to work with so they are a good place to start.
When we run a program on the command line you would be familiar with supplying arguments after it to control its behaviour. For instance we could run the command ls -l /etc. -l and /etc are both command line arguments to the command ls. We can do similar with our bash scripts. To do this we use the variables $1 to represent the first command line argument, $2 to represent the second command line argument and so on. These are automatically set by the system when we run our script so all we need to do is refer to them.
Let’s look at an example.
#!/bin/bash # A simple copy script cp $1 $2 # Let's verify the copy worked echo Details for $2 ls -lh $2
Let’s break it down:
- Line 4 – run the command cp with the first command line argument as the source and the second command line argument as the destination.
- Line 8 – run the command echo to print a message.
- Line 9 – After the copy has completed, run the command ls for the destination just to verify it worked. We have included the options l to show us extra information and h to make the size human readable so we may verify it copied correctly.
user@bash: ./mycopy.sh /projects/file1.data ./results.data Details for ./results.data -rw-r--r-- 18 ryan users 3.4M Feb 14 07:18 results.data
We’ll discuss their usage a little more at a later date.
Other Special Varaibles
There are a few other variables that the system sets for you to use as well.
- $0 – The name of the Bash script.
- $1 – $9 – The first 9 arguments to the Bash script. (As mentioned above.)
- $# – How many arguments were passed to the Bash script.
- $@ – All the arguments supplied to the Bash script.
- $? – The exit status of the most recently run process.
- $$ – The process ID of the current script.
- $USER – The username of the user running the script.
- $HOSTNAME – The hostname of the machine the script is running on.
- $SECONDS – The number of seconds since the script was started.
- $RANDOM – Returns a different random number each time is it referred to.
- $LINENO – Returns the current line number in the Bash script.
Some of these variables may seem useful to you now. Others may not. As we progress to more complex scripts in later tutorials you will see examples of how they can be useful.
Setting Our Own Variables
As well as variables that are preset by the system, we may also set our own variables. This can be useful for keeping track of results of commands and being able to refer to and process them later.
There are a few ways in which variables may be set (such as part of the execution of a command) but the basic form follows this pattern:
variable=value
This is one of those areas where formatting is important. Note there is no space on either side of the equals ( = ) sign. We also leave off the $ sign from the beginning of the variable name when setting it.
Variable names may be uppercase or lowercase or a mixture of both but Bash is a case sensitive environment so whenever you refer to a variable you must be consistent in your use of uppercase and lowercase letters. You should always make sure variable names are descriptive. This makes their purpose easier for you to remember.
Here is a simple example to illustrate their usage.
#!/bin/bash # A simple variable example myvariable=Hello anothervar=Fred echo $myvariable $anothervar echo sampledir=/etc ls $sampledir
Let’s break it down:
- Lines 4 and 6 – set the value of the two variables myvariable and anothervar.
- Line 8 – run the command echo to check the variables have been set as intended.
- Line 9 – run the command echo this time with no arguments. This is a good way to get a blank line on the screen to help space things out.
- Line 11 – set another variable, this time as the path to a particular directory.
- Line 13 – run the command ls substituting the value of the variable sampledir as its first command line argument.
user@bash: ./simplevariables.sh Hello Fred a2ps.cfg aliases alsa.d ...
It is important to note that in the example above we used the command echo simply because it is a convenient way to demonstrate that the variables have actually been set. echo is not needed to make use of variables and is only used when you wish to print a specific message to the screen. (Pretty much all commands print output to the screen as default so you don’t need to put echo in front of them.)
Quotes
In the example above we kept things nice and simple. The variables only had to store a single word. When we want variables to store more complex values however, we need to make use of quotes. This is because under normal circumstances Bash uses a space to determine separate items.
user@bash: myvar=Hello World -bash: World: command not found
Remember, commands work exactly the same on the command line as they do within a script.
When we enclose our content in quotes we are indicating to Bash that the contents should be considered as a single item. You may use single quotes ( ‘ ) or double quotes ( ” ).
- Single quotes will treat every character literally.
- Double quotes will allow you to do substitution (that is include variables within the setting of the value).
user@bash: myvar='Hello World' user@bash: echo $myvar Hello World user@bash: newvar="More $myvar" user@bash: echo $newvar More Hello World user@bash: newvar='More $myvar' user@bash: echo $newvar More $myvar
Command Substitution
Command substitution allows us to take the output of a command or program (what would normally be printed to the screen) and save it as the value of a variable. To do this we place it within brackets, preceded by a $ sign.
user@bash: myvar=$( ls /etc | wc -l ) user@bash: echo There are $myvar entries in the directory /etc
Command substitution is nice and simple if the output of the command is a single word or line. If the output goes over several lines then the newlines are simply removed and all the output ends up on a single line.
user@bash: ls bin Documents Desktop ... Downloads public_html ... user@bash: myvar=$( ls ) user@bash: echo $myvar bin Documents Desktop Downloads public_html ...
Let’s break it down:
- Line 1 – We run the command ls. Normally its output would be over several lines. I have shortened it a bit in the example above just to save space.
- Line 4 – When we save the command to the variable myvar all the newlines are stripped out and the output is now all on a single line.