Bash Variables

Working with variables with Bash

Working with Variables

A variable is simply a place where we can store and retrieve assigned information from. Variable names can only consist of letters either upper case or lower case letters can be sued. It is simple to create and assign a value to a variable, however, we must keep in mind that there are also many system assigned variables. These can normally be identified as they are in UPPER case. These variables are known as environment variables. A list of currently assigned variables can be displayed by issuing the command "env" from the command line. Below is a sample of some of the output that is displayed from the command:


You may also read the contents of a variable by using the "echo" command:

john@john-desktop:~$ echo $PWD
john@john-desktop:~$ echo $LANG
john@john-desktop:~$ echo $PATH

When referencing a variable you must always precede the variable name with a "$" dollar sign. This signifies to the shell that a variable name is being referenced.

Creating and Assigning values to Variables

Values can be assigned to a variable simply by assigning a value to a variable name. Values are assigned by using the "=" sign. No spaces must appear around the "=" sign. For example if I wanted to store my name and my age, I could use the following assignments:


Once we have assigned these values, we can retrieve these values back with the "echo" command:

john@john-desktop:~$ name=john
john@john-desktop:~$ age=21
john@john-desktop:~$ echo $name
john@john-desktop:~$ echo $age
john@john-desktop:~$ echo "My name is $name and I am $age years old"
My name is john and I am 21 years old

Bash read Command

As we saw earlier, we can assign values to variable names. Bash has a very useful command called 'read'. This command accepts a line of input and spits it into variables. Each argument that is read must be the name of a variable:

john@john-desktop:~/scripts$ read firstname surname telephone
john smith 0123456789
john@john-desktop:~/scripts$ echo $firstname
john@john-desktop:~/scripts$ echo $surname
john@john-desktop:~/scripts$ echo $telephone

In the above example, the "read" command reads our input line and breaks it down into individual words. The line is broken down based on spaces. If we wanted to split the line based on a different character, we could modify a special variable called "IFS" Internal Field Separator. By default this is set to a space.

IFS - Internal Field Separator

To change the delimiter used by the read command, we need to modify the value held within the "IFS" Internal Field Separator variable. Note, it is good practise to set the IFS back to its default setting after you have processed your line with the read command.

In the example below we are going to set the IFS variable to "-":

john@john-desktop:~/scripts$ old_IFS=$IFS
john@john-desktop:~/scripts$ IFS=-
john@john-desktop:~/scripts$ read day month year
john@john-desktop:~/scripts$ echo $day
john@john-desktop:~/scripts$ echo $month
john@john-desktop:~/scripts$ echo $year
john@john-desktop:~/scripts$ IFS=old_IFS

The IFS value is set back to its original value by the assignment "IFS=old_IFS". In the above example, if we had not have changed the delimiter to a "-", the read command would have taken the whole line if input into the first variable within the read statement. This can be clearly seen below:

john@john-desktop:~/scripts$ read day month year
john@john-desktop:~/scripts$ echo $day

Exporting Variables

So far we have assigned variables within the shell. However, for a variable to be used within a script, we have to export the value first. By default variables are not passed to other process started by the shell. If we wish to pass a variable to a script or another process, we can use the "export" command. The syntax is literally export variable=value

john@john-desktop:~/scripts$ export myvariable=somevalue

To view any variable that has been exported, we can simply issue the command "export" without any arguments. The output below is an extract of our variable only. You will find that there are many other exported variables which have already been defined and will be displayed within the output. For clarity we have displayed only our entry.

declare -x myvariable="somevalue"

env and set commands

set command

The set command is used to display all variable both local and exported variables. The output from the set command can be quite large. You may wish to pipe your output to a pager such as the "less" pager ( set | less:

john@john-desktop:~/scripts$ set | less


env command

The env command can be used to display only exported variables. It produces the same output as the export command with no parameters.

printf command

Another method that is used to display values contained within variables is the "printf" command. The printf command controls the output of data similar to that of the "printf" command within the "C" programming language". Printf is often used in scripts as it allows you to control the output easily. The easiest way to understand the "printf" command is to take a look at a few simple examples:

john@john-desktop:~/scripts$ printf "I am a single line of text\n"
I am a single line of text

Notice in the above command we used the "\n" at the ender of our line. This sequence specifies a newline. To illustrate this we can split output across several lines:

john@john-desktop:~/scripts$ printf "line 1\nline 2\nline 3\nline 4\n"
line 1
line 2
line 3
line 4

Variables can be displayed in the usual manner by specifying the variable name:

john@john-desktop:~/scripts$ name=john
john@john-desktop:~/scripts$ day=monday
john@john-desktop:~/scripts$ printf "My name is $name\nToday is $day\n"
My name is john
Today is monday

Many other parameters can be passed to the printf command. These can be seen by issuing the command man printf from your terminal. For a full overview of the command you can also issue info coreutils 'printf invocation' from your terminal. Some of the commonly used parameters are below:

\"     double quote
\\     backslash
\a     alert (BEL)
\b     backspace
\c     produce no further output
\e     escape
\f     form feed
\n     new line
\r     carriage return
\t     horizontal tab
\v     vertical tab