2.9. Variables in bash#
Although bash is primarily designed for managing processes, files, and representing everything as text,
its syntax is in actually quite expressive and posses simple programming language constructs.
For example, similar to other programming languages, bash has the ability to use variables.
Variables in bash have various uses, including:
Defining something configurable once, and then easily reusing that definition in various later commands.
Holding some value that is not known in advance, for example text from user input, or the output of some command.
Configuring the shell that you are working in, also referred to as your working environment. This includes, for example, modifying the list of directories where the shell will look for executable programs.
Variables are commonly used in shell scripts, which will be discussed later in Section 2.10, but can also be used when you interact with the shell yourself in a terminal.
Letās start with the basic syntax of using variables.
To set or change a variable, use the following syntax in your bash shell: <variable>=<contents>
For example, try this:
$ MYNAME="A. User"
Note: there should be no space before and after the = sign).
Again, the assigned value = immediately follows the variable name MYNAME, without a space.
The content of a variable is just plain text, and we can now insert this text in commands, just as if we typed it ourselves.
To insert a variableās content in the comment, write $ directly followed by the variable name:
$ echo "My name is $MYNAME"
Observe that the $ is only use to ālook upā the value of a variable, but it is not part of the name itself,
so we should not include the $ when assigning a value to a variable.
Variables can be updated if needed. You can express a variableās (new) value in terms of variables too, of course:
$ MyVal="Hello"
$ echo $MyVal
$ MyVal="$MyVal World!"
$ echo $MyVal
Exercise 2.108
Try out what happens if you use a variable that was not set yet, e.g. echo Start $KJHDS Stop;
Does using an unset variable result in an error, or does it have some default value?
Exercise 2.109
Sometimes variable lookups are placed in quotes, which can have subtle different results compared to looking up the variable without quotes:
$ MSG="Hello World!"
$ echo $MSG
$ echo "$MSG"
Why does the output of echo commands here look different?
Hint: recall Section 2.4.4.1.
A common use for variables is to hold a value that we want to define once, and reuse later various times, e.g. a long filename:
$ MYFILE=/usr/share/common-licenses/GPL
$ head -1 $MYFILE
$ tail -1 $MYFILE
$ wc $MYFILE
Or to capture the output of commands, as was done in Section 2.7.3,
$ TXTFILES=$(find . -name "*.txt")
$ echo "Found: $TXTFILES"
$ wc -l $TXTFILES
Tip
You can use Bashās Tab-completion to complete variable names.
Once you have typed a $ and the first letters of the variable, a single Tab will complete the name.
If multiple variables start with the same letter sequence, the completion will only complete up to the part that they share.
You can press Tab twice to get all variable name options that start with what you currently typed.
You can also use this mechanism to quickly see all set variables, both regular and environment variables,
by trying to complete just $.
For example, by starting to type (donāt press Enter yet),
$ echo $
and then pressing Tab twice, you should see all variables.
Exercise 2.110
Try this exercise in a working directory with several files with a .txt extension.
What is the difference between the two echo commands here?
$ TXTFILES=$(find . -name "*.txt")
$ echo $TXTFILES
$ echo "$TXTFILES"
Exercise 2.111
Continuing the previous exercise, what is the difference between the following two commands?
$ wc -l $TXTFILES
$ echo "$TXTFILES" | wc -l
2.9.1. Environment variables#
A variable can also be marked as a special environment variable, which have several uses.
First, environment variables can reflect properties about your shell environment, such as your username and home directory, and changing them may even affect how the shell works. In fact, some environment variables are already defined when you start a new shell.
Second, unlike regular variables, environment variables are passed on to any program that you start in the shell. This means a program may access your environment variables, and adjust their behavior based on their set values. For example, a program can obtain your home directory from an environment variable, and use it as a default location to save its files. But a program can also be programmed to look for an optional environment variable that could set to configure specific settings.
Some common environment variables are:
HOMEis the environment variable which contains your home directory;PATHcontains a list of directories the shell will search for programs;TERMshows you what type of terminal you are working on.
Some of the environment variables contain useful information, such as USER, and PWD etc.
You can get a list of environment variables (without regular variables) and their current values
with the env command,
$ env
Exercise 2.112
Get a list containing only all environment variables that contain your user name, using a single command.
Hint: use a combination of env, grep, and a pipe.
You use environment variables just as you would use regular variables, for example:
$ echo "My name is $USER and my home is $HOME"
Some of these variables affect how your shell behaves.
For example, when you write ~ to represent your home directory as part of a path,
$ cd ~
your bash shell will lookup the value of the HOME variable, and replace the ~ by that value.
So this line is equivalent to
$ cd $HOME
Another useful environment variable to familiarize yourself with is PATH, which we will discuss later in Section 2.10.6.
2.9.2. Defining new environment variables#
You can also define your own environment variables.
To mark a variable as an environment variable, write export before setting the variable, e.g.
$ export NEWENVVAR=Hi
Check the output of env if NEWENVVAR is listed.
Exercise 2.113
Letās try to set a variable, and test what env reports.
$ MYNAME="A. User"
Does env also show regular variables?
Exercise 2.114
Test if changing the value of an exported variable is reflected in the environment:
$ export NEWENVVAR=Hi
$ NEWENVVAR=Hello
What value does env report?
Exercise 2.115
Set an environment variable, and confirm with env that it is properly set.
Then close the terminal, which will terminate your shell session.
Now open a terminal again, restarting a shell.
Was the environment variable still set (check with env again)?
Note
Just like aliases, custom set environment variables are lost when you logout,
unless you put them in your .profile file.
2.9.3. Environment variables and child processes#
As explained before, environment variables are also accessible in child processes.
We can simply test this by starting a child bash process from in your existing bash session.
Close your terminal, and open a new one, to make sure you have no custom variables set yet.
Letās set two variables, one regular and one an environment variable:
$ TEST_REGULAR=Foo
$ export TEST_ENV=Bar
Letās confirm that both variables can be used now
$ echo $TEST_REGULAR $TEST_ENV
should show Foo Bar.
Next, start a new bash process,
$ bash
You should see a normal prompt again, but you should be able to confirm you are now working in a child bash process,
$ pstree
Letās check which of the two variables are now set, using the same test as before:
$ echo $TEST_REGULAR $TEST_ENV
You should be able to confirm from the output that only the exported environment variable TEST_ENV was kept.
Exercise 2.116
Does setting a variable value in a child process affect the parent process? Letās test it by setting two different values
$ TEST_REGULAR=Ping
$ export TEST_ENV=Pong
Then terminate the child process using exit, and confirm with pstree that you are back in your original shell process.
What do you think the values of these variables in the parent process are? After you made your guess, show the variable values one more time:
$ echo $TEST_REGULAR $TEST_ENV
Exercise 2.117
As in the previous exercise, start a child bash process,
and this time try to set a new environment variable that was not yet set in the original parent bash process.
Now exit the child process, and check if you can print the value of that variable in the parent process, and if it shows up with env.
Draw a conclusion from your findings: Can a child process add new environment variables to a parent process?