If the
shell were only used to enter a few commands interactively,
it would be of limited usefulness.
Where it truly becomes useful is in automating tasks expressed as a
script that chains and combines elementary commands.
It was noted at
this stage that, for this tutorial series,
the
/root/SHARED directory on the guest system was shared with the
SHARED directory on the host system.
For convenience
But this is not mandatory; it is possible to use nano or vi
directly from the guest system.
, it is recommended to write scripts from the host system using the
editor of your choice; the guest system will then only need to execute
them.
On the host system, create the file
SHARED/script.sh with the
following initial content:
echo "==== my script begins ===="
date
tree /var/log
echo "==== my script ends ===="
Run it from the guest system as follows:
bash SHARED/script.sh;
make sure you understand what you observe.
During this invocation, the
bash interpreter, which executed the commands
in this script, was explicitly specified on the command line
The principle is identical to running python my_prog.py.
It would also have been possible to use sh, since on this system it
is a link to bash (see the command ll /bin/sh).
.
As it stands, the file is not yet considered a program by the system, but
merely as plain text; the invoked
bash program is responsible for
reading its content and executing the recognised commands.
Using the command
ll SHARED/script.sh, you can see that this file
has the
r (read) and
w (write) attributes but no
x
(executable) attribute
The
rwx attributes of files and directories will be covered
in the tutorial on
user management.
.
For greater convenience, it is generally customary to place the line
#!/bin/bash at the very beginning of the script and to make this file
executable with the command
chmod +x SHARED/script.sh.
The system will now be able to recognise this file as a program, and the
#! indication at its very beginning (the
shebang) will tell it
which interpreter to launch in order to execute its content.
Verify that this file now has the
x (executable) attribute and run it
simply with
SHARED/script.sh.
Give
SHARED/script.sh the following new content:
#!/bin/bash
for my_var in Uno Due Tre Quattro ; do
echo "my_var is ${my_var}"
done
Try it and observe the result carefully.
Make sure you understand the principle of the for loop and that of
variable substitution with
${my_var}
Strictly speaking, $my_var is sufficient to substitute the
my_var variable.
Curly braces are a good habit to adopt because there are cases where
a variable is concatenated with other text.
For example, if my_var contains AB, then
${my_var}CD is ABCD whereas $my_varCD
does not exist.
.
Now try again with this other version:
#!/bin/bash
directory=${1} # first argument on command line
for entry in ${directory}/* ; do # all entries in the directory
if [ -d ${entry} ] ; then # test if this entry is a directory
echo "${entry} is a directory"
fi
done
Use it as follows
SHARED/script.sh /etc/systemd or
SHARED/script.sh ., and make sure you understand
the principle behind it.
Beyond the variables that we introduced locally in our script, it is
possible to use others that are passed to invoked programs (and
therefore to scripts): these are
environment variables.
Create a new minimal script
show_vars.sh with the following content:
#!/bin/bash
echo "PATH: ${PATH}"
Make it executable and run it in this way
show_vars.sh;
observe the reason for the failure.
Try again in this way
./show_vars.sh; now the program is found
and displays the content of the
PATH variables.
Prepending
./ when launching the script specifies that this program
should be searched for in the current directory (in the same way that
SHARED/script.sh indicated that it was in
SHARED).
The
PATH environment variable displayed by this script represents the
list of directories in which commands are searched for.
This explains why commands such as
ls or
tree are implicitly
found in
/usr/bin, whereas for our own scripts we must specify the
directories that contain them.
Verify this using the commands
which tree,
which ls and
which show_vars.sh, which use the
PATH environment variable
to indicate the location of the requested program.
Complete the
show_vars.sh script in the same way to display the
USER,
HOME and
MY_VAR variables, then run the script
again.
You should observe that the environment variables
USER and
HOME
are already set and have entirely predictable values.
However,
MY_VAR currently has no value in this script.
In the current
shell, enter the command
MY_VAR="hello world"
and verify it with
echo ${MY_VAR}.
Run the script again and observe that this variable has remained local
to your
shell, since the script still does not recognise it.
In the current
shell, enter
export MY_VAR and run the script
again to observe that it is now passed on.
This variable is no longer local to the current
shell but has become
an environment variable that is propagated to the programs launched by
this
shell.
All of this is only a brief introduction to
shell scripts.
Beyond the command line, the
UNIX shell was designed as a
fully-fledged programming language with a wide variety of features.