Using the BASH shell

What shell am I using?

It's possible you don't know what shell you are working with, particularly if you have accounts on several machines. So let's simply remark that, usually, the system administrator for your Unix computer assigns you a default login shell. Your login shell is the shell that will take your commands and "interpret" them to the underlying operating system. There are common shells, in particular: the Bourne shell, the C shell, the Korn shell, the T shell, the "Bourne again" or "bash" shell.

Many features are shared by all the shells. For instance, you always say ls to list your files. But some useful and interesting features are unique to each shell. The comments in this document focus on the bash shell.

When you login, your interactive session begins with one of these shells assigned to you by default. This is your login shell. There is an environment variable which records the name of this shell, or actually, the path of the shell program. To find out what your shell is, you can ask to print the value of this environment variable:

So all you have to do is ask for the value of this variable, by typing the following command, which should work no matter what shell you use:

echo $SHELL
If you are running the bash shell, the response will be something like

Changing Your Shell:

Your computer account is set up in such a way that you have been assigned a default shell. Whenever you log in, or whenever a program of yours executes, it is the responsibility of this shell to mediate between you and the computer, that is, to interpret your commands and to carry them out.

You can change the shell you are working with, either temporarily, or permanently.

Temporarily Changing Your Shell:

At any time when you are logged in, you can request another shell temporarily, simply by invoking its name. At that point, the shell you were using doesn't terminate, but goes on "hold", and you begin talking to the new shell. When you terminate your conversation with the new shell, you find you are back talking to your original, default shell.

In particular, to start a conversation with a new shell, you essentially simply name the shell, which is the same as asking that program to run. So we might start the C shell by typing

although it might be necessary or safer to invoke the full path, which might be

To terminate the new shell, you can try some obvious commands like "quit" or "exit"; since you are essentially an input file, as far as the shell is concerned, it is often possible to terminate the shell session using the command "^D", that is, CONTROL-D.

Permanently Changing Your Shell:

To permanently change your default login shell, use the chsh ("change shell") command, along with the "full name" of the shell program you want. To convert to the Korn shell, for instance, you might type

chsh -s /bin/ksh

Of course, this command only takes effect when you next log in.

The FOR loop:

The FOR statement allows you to set up a loop in a shell script.

One form of such a loop is similar to a loop in C or FORTRAN, in which it executes a set of statements a certain number of times:

        for var := low to high do

Another version of the loop allows you to carry out commands for each file in a list:

        for filename in list do
In this example, list could be an explicit list of names

A user had thousands of files whose name began with "snap3d". He wanted to move them to another directory. However, typing the command line

        mv snap3d* newdirectory
failed because the shell replaced the user's commandline by the explicit list of files. That list was so long it exceeded an internal limit on the length of the command line. The user was forced to move the files in groups. Instead, the following shell script could be used to move all the files:

        for file in $( ls snap3d* ) do
          mv file newdirectory

Exit Status:

You may be aware that each C program includes the declaration int main(), because a C program can be regarded as a function that returns an integer value to the operating system. This value is typically 0 for satisfactory conclusion, and nonzero (and usually positive) otherwise.

BASH records the value returned by the most recently executed program, script, or command, as the symbolic variable "$?". Thus, you can run a program and query its return status, as follows:

        echo $?

Since a nonzero return generally indicates an error, you can use this value to control the behavior of a script that should terminate if any error is encountered:

#  Script is about to compile a program.
gfortran calpak_prb.o -L$HOME/lib/$ARCH -lcalpak
#  If the compilation failed, then we need to quit now.
if [ $? -ne 0 ]; then
  echo "Errors linking and loading calpak_prb.o"
#  ...otherwise script continues...

Symbolic Variables:

The BASH shell sets up certain symbolic variables automatically, and allows you to add other variables that you find useful, to determine or change their values, and to carry out other actions based on those values.

By convention, symbolic variables are usually given upper case names. This helps to distinguish them from the lower case names used for system commands and so on.

The BASH shell will automatically define a large number of variables. To see the current list, use the env or printenv command:

> env

Notice, for instance, the variable called MODE which has the value INTERACTIVE. This indicates that this BASH shell corresponds to an interactive session. If we had run a script, that script creates a separate BASH shell, with its own set of variables and values. For that script, the variable MODE would have the value BATCH. To discover the value of a variable, it is necessary to put a dollar sign in front of the name.

For instance, to print the value of MODE, we would use the echo command:

        > echo $MODE

The value of symbolic variables such as MODE can be used to control other actions. In fact, this is their main purpose. For example, the HOME variable defines the directory where any new session will begin, typically called your "login directory". The actual value of HOME is sometimes a long, cumbersome, forgettable name. We can use the symbolic variable in system commands instead:

        ls $HOME
        cd $HOME/data/survey
        cp file.txt $HOME

To create your own shell variable, you use a formula of the form


The EXPORT Command:

Each new UNIX process created by the BASH shell gets a copy of the standard symbolic variables. The user can add new variables to this set or modify existing variables. However, generally these changes remain local to that particular process. In particular, if the user sets a variable, and then runs a script, the values of that variable will normally not be "inherited" by the script, since it will get a fresh set of variables from the shell.

In order to create a variable whose name and value will be inherited by all subprocesses, it is necessary to use the EXPORT command.

A compact form of this command creates the variable name, assigns it a value, and declares it to be exportable, all in one line:

        export COMPILER=/usr/bin/gcc

The one line command is a combination of two separate commands, one that defines the variable:

and one that makes it exportable:
        export COMPILER

Customization Files:

The bash shell provides a method by which you can store local information and personal shortcuts that will be automatically accessible. You can also specify that certain programs be run every time you log in.

You do this by creating files with special names and placing them in your home directory, called .bashrc and .bash_profile. C shell users may recognize these are corresponding to the ".cshrc" and ".login" files used by that shell.

The file .bashrc contains definitions and actions that you want to happen every time you log in interactively, and every time you run a script that uses the bash shell. This might include modifications to your PATH variable.

Here's an example of a .bashrc:

#  .bashrc  19 November 2008
umask u=rwx,g=rx,o=rx
#  Modify the path.
#  Aliases required for BATCH and INTERACTIVE use.
alias F77='/usr/local/bin/gfortran'
alias F90='/usr/local/bin/gfortran'
alias gcc='/usr/local/bin/gcc'
alias g++='/usr/local/bin/g++'

The file .bash_profile contains definitions and actions that you want to happen only for interactive sessions. This might include setting the prompt string, for instance.

Here's an example of a .bash_profile:

#  .bash_profile  27 March 2009
export ARCH=OSX
source ~/.bashrc
PS1="OSX bash> "
#  Set up some command shortcuts.
alias lookfor='~/bin/lookfor'
alias ls='ls -F'
alias rm='~/bin/remove'
alias staff='~/bin/staff'
#  Run some simple programs every time you log in.

It's probably best to keep the .bashrc file small and uncluttered. On the other hand, the .bash_profile might include a call to the cal program to print out a calendar, or perhaps might run a command to show you your current disk usage.

Because these files have names that begin with a period, the ls command will not include them in a usual listing. To see them, you need to include the a (for "all") switch on the ls command:

        ls -a
(You will probably be surprised to see 10 or 20 other "dot" files that are normally hidden. It's a popular way for various programs to store information from previous sessions, something like Internet cookies.)

You can return to the HTML page.

Last revised on 13 June 2012