Bash and Shell Scripting
Bash Shell
There are often several different shells installed on a Linux system. bash
is
probably the most common, and is typically the default for new users on any
system. bash
is running in the terminal, and it interprets and executes the
commands we type in.
Environment
User Configuration
On startup, such as when a new terminal is opened, or you connect to a remote
system over the network, bash
will read several configuration files depending
on how it detects it is running.
- For login shells (shells where you are prompted to login when you start it),
bash
will read configuration options in~/.bash_profile
or~/.profile
if these exist. Note~
is interpreted by the shell as the users home directory. - For non-login shells (such as when you open the terminal emulator)
bash
will read configuration options in~/.bashrc
. - A lot of the time, for simplicity, many people will put all their
configuration options in
~/.bashrc
and leave their~/.profile
empty except for a command to read the~/.bashrc
file.
These files can be used to configure many aspects of the shell, such as how the prompt looks in the terminal.
Environment Variables
Many important aspects of how bash
behaves are governed by environment
variables. These can be modified to your preference in your configuration
files. To see the current value of one of these variables you can do, e.g.
echo $PATH
. A $
symbol is used when referring to the data stored in a
variable, and echo
is a built-in bash command that outputs something to the
terminal.
PATH
: this tells bash which directories to look in for executables so they can be run without typing in their full path. For example, we can just type ingedit
in the terminal to launch the program, as thePATH
variable contains the directory holding an executable of this name. Different directories are separated by ":".- To add the directory
~/.bin
to your path, you can add the lineexport PATH="~/bin:$PATH"
to the.bashrc
file. Here theexport
statement is used to allow the variable to be usable by any child processes rather than local to the script. Note when we are naming the variable we want to assign a value to we don't use a$
. Also we just want to add a directory to the existingPATH
so we add:$PATH
to keep all the existing directories.
- To add the directory
Scripting
Shell scripts allow you easily string together sets of commands in a useful way. For example, you could write a script that runs a calculation, parses the important results to another file, and then generates a plot.
This course will only be able to briefly cover scripting. If you're interested in developing more advanced scripts, I strongly suggest referring to the Advanced Bash-Scripting Guide.
The basics
A simple example script to output "Hello World!" is as follows:
1 2 3 4 |
|
- The first line tells the system what command is used to interpret the
contents of the script. This line should always begin with
#!
and then the path to the executable. Forbash
the executable will almost always be/bin/bash
. - Comments being with
#
. - Commands can be entered otherwise as you would enter them to the terminal.
- Try creating a file called
hello.sh
with the contents listed above. - You will need to make the script executable with
chmod u+x hello.sh
. - Then you can run it by typing
./hello.sh
.
Variables
Variables don't need to be declared in any way, you can assign a value and start using them. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
You can also read a value from stdin using the read
command as follows:
1 2 3 4 5 6 7 |
|
Capitalization
Note: variable names are case sensitive in bash. The usual convention used is
that environment variables (such as PATH
), and internal shell variables
(such as BASH_VERSION
) are capitalized, while other variables are in
lowercase. Adopting this convention will ensure that you don't accidentally
overwrite any important variables in your scripts.
Command Substitution
Command substitution allows the result of a command to replace the command itself, acting much like a variable in practice. For example:
1 2 3 4 5 6 7 8 9 |
|
Conditional Statements
if
statements can be used in bash, and many types of tests are possible.
You can test if the value stored in a variable equals something as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
We can also check, e.g., if a file or directory exists:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Note, bash can also use the [[ ... ]]
test construction rather than
[ ... ]
, with the former offering some more options and functioning more like
other programming languages, though it won't work in many other (non-bash, or
older bash version) shells.
Arithmetic and Testing
To test numeric values, the (( ... ))
construction can be used. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
For Loops
For loops iterate a variable over a range of values. For example:
1 2 3 4 5 6 7 8 9 |
|
A for loops can be used to apply a command repeatedly to a set of files. For example:
1 2 3 4 5 6 7 8 9 10 11 |
|
Bash also supports numeric loop ranges using the syntax
{start..finish..increment)
. For example
1 2 3 4 5 6 7 |
|
While Loops
Bash also supports while loops, where a set of commands are repeated continuously while a given condition is true. For example:
1 2 3 4 5 6 7 8 9 10 11 |
|
It is often convenient to use while
loops to operate on every line of a file.
For example:
1 2 3 4 5 6 7 8 9 10 11 |
|
Arguments
We can also pass arguments to bash scripts from the command line. For example:
1 2 3 4 5 6 7 8 |
|
We can loop over arguments using a for loop as follows:
1 2 3 4 5 6 7 |
|
Functions
We can also define functions in bash as we would in other languages. These allow sections of code to be reused as needed and can help make a script easier to follow.
A simple example is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|