23. Bash Scripts

Bash can read and execute commands from a file with the extension ".sh". The file extension is the same under UNIX Shell:

$ echo "echo \$0, \$*" > bin/commands.sh

These files are called Bash scripts. To execute commands from a file apply its path to the bash command:

$ bash bin/commands.sh

To execute the commands from file like any command the executable flag of the file has to be set:

$ chmod u+x bin/commands.sh

If the file could not be found within a directory, that is listed in the PATH parameter, the relative:

$ ./bin/commands.sh

or the absolute path of the file has to be used:

$ /home/pa/bin/commands.sh

To find a command, which parent directory is not listed in the PATH variable:

$ echo $PATH
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

the name of the directory is appended to the value of PATH by:

$ PATH=$PATH:~
$ commands.sh

To ensure, that the Bash interpreter is used a "#!/bin/bash" shebang is set into the first line of the script:

#!/bin/bash
echo $0, $*

The shebang treats referenced interpreter to execute the following lines. Even Perl, Python or Ruby start this usually. Script parameters are set after the command name:

$ commands.sh param1 param2

The parameter values are accessiable through the positional parameters: $1, $2,... All parameters can be selected by the $@ or $* parameters. $0 holds the script name. Options can be parsed using the getopts command:

#!/bin/bash
while getopts "ne:" optname
do
 case $optname in
  n) echo "-n - no value expected";;
  e) echo "-e - $OPTARG";;
 esac
done

The expected options are listed after getops. Options that require a value are marked by a following ":" operator:

$ options.sh -e
/home/pa/bin/options.sh: option requires an argument -- e

Each time getopts is called, the next option name is stored in the variable optname and it's value in the OPTARG parameter:

$ options.sh -n -e "A Clockwork Orange"
-n - no value expected
-e - A Clockwork Orange

Beware of word splitting: Without double quotes the value of -e expands "A" only:

$ options.sh -e A Clockwork Orange
-e - A

To process a Bash script in situ the source command or its alias the "." operator are used:

$ . bin/options.sh

In contrast to the script execution described above: The execution is done within the current shell. source or "." enables the possibility to reuse the code of a scripts like a library. But the commands are read and executed immediately.

Bash scripts are processed in a separate shell. Their execution environment is inherited from the context in which it was started. Depending on the invocation a shell will be read and executed from various locations. This files holds parameters like PATH. On startup, interactive login shells, started by:

$ exec -l bash

or shells started with --login:

$ bash --login

read and execute commands from /etc/profile and from first file found of either ~/.bash_profile or ~/.bash_login or ~/.profile. So if ~/.bash_profile is found, ~/.bash_login and ~/.profile not read. Note: The latter executed file overwrites variables, traps, and functions of the previous. An interactive non-login shell:

$ bash

reads and executes commands from ~/.bashrc. Usually, .profile contains a reference to .bashrc:

if [ -f "$HOME/.bashrc" ]
then
  . "$HOME/.bashrc"
fi

The none interactive shell, like:

$ bash bin/commands.sh

reads and executes commands from the file referenced by the variable BASH_ENV. Note: Invoking a Bash script by exec system call, like cron does, leads to an environment determined by the BASH_ENV variable. The environment that is formed for the script started in a login shell is determined by /etc/profile and either ~/.bash_profile or ~/.bash_login or ~/.profile as well as the history of the interactive session.

~/.bashrc or ~/.profile are approbative locations for customizing a shell. Aliases and environment variables can be recorded:

alias make="make -C ~/daten bashscripting"
export ORATAB=LMS