Bash Scripting – Variables Explained With Examples

Variables are very important concepts in any programming language you work with. Think of a variable as a container in memory that stores data of a certain type. The main purpose of variables is to store a value and access it later for processing. If you are someone from other programming languages like Java, C, C++, you may find differences in how the variable definition differs since Bash does not have a strong type system.

Bash handles two types of variables. They are:

  • User-defined variables : Variables that you create and manipulate.
  • Environmental variables : Created and stored by bash or applications for the system/Application purpose.

We will start working with user-defined variables followed by environmental variables.

1. How to create a variable

The variable should have an identifier (variable name) and a value assigned to it like shown below. The identifier (variable name) is "site_name" and the value assigned is "OSTechnix".

$ site_name="OSTechnix"
$ this_year=2021
$ value_of_pi=3.14

There are few things to remember when creating variables.

  • There should be no space between variable name and value.
  • Try to avoid using names that are already used such as reserved bash keywords, variable and function names which will create conflict.
  • Create descriptive variable names and variable names can have letters, numbers, underscores, and digits.

The variable naming convention is debatable since I have seen different people use different conventions to create variable names. Some create user-defined variables using snake case as I created in the previous example and some create variable names with full caps. There are no strict rules in bash but be consistent with whatever method you choose. I prefer to name my variables in snake case and constants to be in caps.

2. How to access Bash variables

There are two ways to access a variable. One is using "$ symbol" followed by the variable name and the second method is using the "$ symbol" followed by curly braces and variable name inside the curly braces.

$ echo $site_name
OSTechnix $ echo ${this_year}
2021
$ echo ${this_year} $value_of_pi
2021 3.14
Access Bash variables
Access Bash variables

3. Re-assign value to a variable

Bash has no strong type system meaning there are no strict rules in defining the data type when creating the variables. Bash variable stores all the values as strings and it smartly knows when we work with numeric computation.

You can reassign any values to a variable that is already created.

$ os_name="PoP_OS!"
$ echo ${os_name} $ os_name="Linux Mint"
$ echo ${os_name}
Re-assign value to a variable
Re-assign value to a variable

4. Declaring datatype for a variable

You can use the declare command to create a variable with a specific data type. Access the help section of declare command to know more about it.

$ declare --help
Accessing help for declare command
Accessing help for declare command

For example, if you wish to create a variable with the int data type, you can use the declare command with the -i flag.

$ declare -i pi
$ pi=3
$ echo $pi
3
$ pi=3.14
bash: 3.14: syntax error: invalid arithmetic operator (error token is ".14")
Declaring data type for variables
Declaring data type for variables

Remember, the declare command is a way to manipulate the attribute of your variable but do not expect a strong type system from declare command as in other programming languages.

5. Command output to a variable

You can run any bash commands and store the output of the command to the variable. You have to run the command within $() like below and later use the variable for further processing.

$ today_date=$(date)
$ echo ${today_date}
Saturday 11 September 2021 08:53:25 PM IST
Storing output to a variable
Storing output to a variable

6. Using quotes with variable

In bash, single and double quotes behave in two different ways. Single quotes will prevent the expansion and treat the value as literal. Double quotes will allow expansion.

Take a look at the below example. I created a variable named "which_year" and running a command along with a string. When I use double quotes the date command will be expanded but when single quotes are used the date command will not run and is stored as it is in the variable.

$ which_year="I am in year : $(date +%Y)"
$ echo ${which_year}
I am in year : 2021
$ which_year='I am in year : $(date +%Y)'
$ echo ${which_year}
I am in year : $(date +%Y)'
Single and double quotes behaviour in Variables
Single and double quotes behaviour in Variables

7. Removing the variable

You can remove the variable using the unset command.

The Unset command removes the values and attributes of variables and functions.

You can either use unset with -v flag which points to a variable or just unset command which by default first checks for variable definition and unset it.

$ echo ${which_year}
$ unset -v which_year (or) unset which_year
$ echo ${which_year}
Unset variable
Unset variable

For more details, refer unset command help section.

$ unset --help

8. Read-only variable

A read-only state means you cannot change the value or remove the variable once it is created. There are two ways to create the read-only variable.

Use bash built-in readonly to create the read-only variable.

$ readonly var1="This is a readonly variable"

Alternatively, you can use the declare command with the -r flag.

$ declare -r var2="This is a readonly variable too"

You cannot reassign or unset the readonly variable value, it will throw an error.

$ var2="Reassigning with new value"
bash: var2: readonly variable
$ unset var1
bash: unset: var1: cannot unset: readonly variable
Readonly variable
Readonly variable

9. Bash built-in special variables

Bash has some special built-in variables that are dedicated to storing certain results. Take a look at the below list of variables.

$? = Stores exit status of last ran the command.
$$ = Stores process ID for your bash session.
$0 = Script name.
$1 .. $9 = Arguments passed to the script.
$# = Count the length of values
[email protected], $* = Stores array of all values.

9.1. Exit status ($?)

Every Linux command you run has an associated exit code from (0-255). Zero points to success and the rest points to failure with a different meaning.

$ whoami
$ echo $?
0
$ asdf # WRONG COMMAND
$ echo $?
127
Exit status code
Exit status code

9.2. Process ID ($$)

Using $$ operator, you can get the bash process ID. If you run it from the terminal it will give you the process id for your current session.

$ echo $$
195777 # PROCESS ID OF MY CURRENT TERMINAL SESSION
Bash process id
Bash process id

9.3. Script name & arguments ($0-$9)

Arguments can be passed to your scripts and you might have already been using them in your day-to-day life. Take a look at the id command which accepts username as the argument.

$ id karthick
uid=1000(karthick) gid=1000(karthick) groups=1000(karthick),4(adm),27(sudo),119(lpadmin),998(docker)

Similarly, you can create scripts that accept arguments. Create a sample shell script and copy/paste the following snippet in it.

cat > main.sh
#!/bin/bash echo "+ script_name=$0 "
echo "+ first_argument=$1 "
echo "+ second_argument=$2 "
echo "+ third_argument=$3 "

Now run the script and pass arguments. I am passing 1 to 3 as arguments. $0 picks up the script name with absolute path since I passed the absolute path and $1 to $3 is assigned with respective arguments passed.

$ /home/karthick/main.sh 1 2 3
+ script_name=/home/karthick/main.sh 
+ first_argument=1 
+ second_argument=2 
+ third_argument=3 
Arguments passed to script
Arguments passed to script

9.4. Length of a value ($#)

Using $#, you can calculate the total number of arguments passed or count the length of any values. Take a look at the below example. Prefix the variable name with # and it will print the length of the value instead of the actual value.

$ site_name="OSTechnix"
$ echo ${#site_name}
9
Length of string
Length of string

10. Variable scope

It is important that you understand the scope of a variable. When you create a variable either in terminal or through shell script that variable is bound and available only to that session. You can also say it as a local variable. If you try to access the variable from other sessions the variable will not be available.

Take a look at the below image which will give you a good understanding of what happens. 

  1. Create variable site_name="OSTechnix" from your current shell and access the variable.
  2. Use the $$ variable to see which session you are in.
  3. Create a new bash session by typing "bash".
  4. Try accessing the variable site_name from this session. You will get empty output which is the default behavior in bash.
  5. Exit the new session by typing "Exit" and now try accessing the variable and you will be able to access the variable.
Variable scope
Variable scope

If you wish to access the variable globally from any sessions you have to use the export command which will make the variable available to be accessed in all child sessions/processes created from your current session.

$ site_name="OSTechnix"
$ export site_name

Or

$ export site_name="OSTechnix"
$ bash
$ echo ${site_name}
Exported variable
Exported variable

You can get the list of variables to be exported by typing "export" from the terminal. You will get both environmental and user-defined variable lists.

$ export
List of exported variables
List of exported variables

11. Environment variable

Till now we have seen how to work with user-defined variables. In the introduction section, I mentioned bash supports environmental variables. This set of variables will get loaded when you start your bash sessions and they are maintained by bash. These environmental variables are used by the applications to decide the behavior.

For example, nano is set as the default editor for editing crontab. If I wish to use Vim instead of nano, I can set the EDITOR env variable and crontab will check for this environment variable and use it.

$ export EDITOR="vim"
$ crontab -e

Heads Up: Your variable is bound only to your current session. If you wish to make it persistent you have to put it in ~/.bashrc or ~/.bash_profile.

You can get the list of environmental variables by running the "printenv" command. You will see the environmental variables are defined with capital letters.

$ printenv
Print environment
Print environment

You can also access the particular environmental variable with the printenv command. Below are some of the common environmental variables you will come across.

$ printenv USER # PRINTS USER NAME
karthick
$ printenv HOME # USER HOME DIRECTORY LOCATION
/home/karthick
$ printenv PWD # PRESSENT WORKING DIRECTORY
/home/karthick
$ printenv SHELL # WHICH SHELL I AM USING NOW
/bin/bash
$ printenv PATH # PATH WHICH IS USED BY BASH TO CHECK AND RUN COMMANDS
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Print important environmental variables
Print important environmental variables

Conclusion

In this Bash variables guide, we started with a brief introduction about variables and how to create, access, change and unset in their respective section. And then we have seen what is the difference between user-defined and environmental variables. Try to explore the list of environmental variables that are loaded in your sessions which will give you a good understanding of Bash.

Related read: