This lecture looks at the basic concepts of shell programming, such as
variables, loops and conditional statements. It also looks at quoting
mechanisms and command substitution.
Command language programming
Command interpreters recognise programming languages, that act on files and
programs. They may be general languages such as the Algol-based WFL for Burroughs,
or special purpose languages such as command.com. These languages allow lots
to be done without having to deal with the low-level programmers API.
Unix shell variables consist of a sequence of letters, digits and the underscore,
beginning with a letter. Variables are not declared.
From now on we only discuss the Bourne shell, Korn shell, zsh and bash. The
csh and tcsh have different syntax.
Assignment to a shell variable is by
variable=value
NB: there are no spaces either side of ``=''
To use the value of a variable, prefix it with a ``$''
Example
There are some occassions when you need the value of the variable to be immediately
followed by text. The variable name may be enclosed in curly brackets
x=fred
echo ${x}dy
There are many occasions when you want to execute a command and keep the result
around. For example, you may want to keep the list of files in the current
directory stored in a variable.
The grave command `...` runs the command between
the accents and leaves the result in place.
In any of the shells, arithmetic may be done using the expr command
x=2
y=`expr $x + 2`
bash also allows you to do arithmetic using the let command
x=3
let y=$x+4
The syntax of this command is
for vbl [in values]
do
commands...
done
NB: the words ``for'', ``do'', ``done'' must be the first words on the line.
The commands can be any set of commands.
Example
Example
cd ~/..
for i in os*
do
echo "A student is $i"
done
A common case is to loop through all the command line arguments
(positional parameters).
for i in $*
do
echo "an arg was $i"
done
A shorthand for this is to omit the in $*:
for i
do
echo "an arg was $i"
done
There are conditional expressions and while loops which use Boolean values.
Commands act on files and produce visible output. Where is the Boolean value
from running a command?
Every command succeeds or fails. eg.
rm. may succeed at removing a file, or
may fail to remove another file because of permission problems. An exit code
holds this value.
The exit code is not visible. The exit code of the last command
is stored in the shell variable ``?''.
A value of zero stands for success, anything else for failure.
Generally, the exit code is not documented anywhere. The commands ``test''
and ``expr'' are the best documented, because they are often used in Boolean
expressions.
The syntax is
while commands
do
commands
done
The list of commands in the Boolean part is executed each time round the loop.
Usually this list is just one command, but it may be a pipeline. The exit code
of the last command in this list is used as the Boolean value. If it is True
(exit code zero), the commands in the body are executed.
Example
print the first 20 integers
I/O can be redirected from an entire while loop:
The syntax is
case value in
pattern) commands;;
...
pattern) commands;;
esac
The value is some string or integer. The patterns the use shell globbing mechanism
of * and ?. The matches of value to pattern take place strictly top-to-bottom,
and the first match is used.
Example
Test if variable x contains a single character value, two characters, or more:
There are some characters special to the shell, such as * and ?. The * is also
special in regular expressions. If you attempt
sed s/.*//
the shell will read the * and attempt to glob it. sed will then get a list
of files and complain. A quoting mechanism is used by the shell to stop it
interpreting characters it shouldn't.
Interpretation of a single character is turned off by prefixing it with a backslash
`\' as in
echo the amount is \$20
To echo a `\' itself, use \\.
Enclosing something in single quotes '...' turns off all interpretation, including
interpretation of $, * and \.
Enclosing something in double quotes "..." allows $variable substitution but
no other.
Single quotes in this sed command will turn off variable substitution.
No quotes cause an error.
Write a shell script that takes one parameter. This parameter is a command
that is to be run on all ordinary files in the current directory, and recursively
in every subdirectory
script=$0
command=$1
for f in *
do
if [ -d $f ]
then
cd $f
$script $command
cd ..
else
$command $f
fi
done