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:
PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games DESKTOP_SESSION=ubuntu PWD=/home/john GNOME_KEYRING_PID=2151 LANG=en_GB.UTF-8 MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path UBUNTU_MENUPROXY=libappmenu.so COMPIZ_CONFIG_PROFILE=ubuntu GDMSESSION=ubuntu
You may also read the contents of a variable by using the "echo" command:
john@john-desktop:~$ echo $PWD /home/john john@john-desktop:~$ echo $LANG en_GB.UTF-8 john@john-desktop:~$ echo $PATH /usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
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@john-desktop:~$ echo $age 21 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@john-desktop:~/scripts$ echo $surname smith john@john-desktop:~/scripts$ echo $telephone 0123456789
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 25-12-2013 john@john-desktop:~/scripts$ echo $day 25 john@john-desktop:~/scripts$ echo $month 12 john@john-desktop:~/scripts$ echo $year 2013 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 25-12-2013 john@john-desktop:~/scripts$ echo $day 25-12-2013
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
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 BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_COMPLETION=/etc/bash_completion
The env command can be used to display only exported variables. It produces the same output as the export command with no parameters.
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