Shell Scripting Overview
Shell Scripting Overview
Notes
• $* and $@@ when unquoted are identical and expand into the arguments.
• "$*" is a single word, comprising all the arguments to the shell, joined together with spaces. For example '1 2'
3 becomes "1 2 3".
• "$@@" is identical to the arguments received by the shell, the resulting list of words completely match what was
given to the shell. For example '1 2' 3 becomes "1 2" "3"
Reading user input
To read standard input into a shell script use the read command. For example:
echo "Please enter your name:"
read name
echo "Welcome to Edinburgh $name"
This prompts the user for input, assigns this to the variable name and then displays the value of this variable to standard
output. If there is more than one word in the input, each word can be assigned to a different variable. Any words left over
are assigned to the last named variable. For example:
echo "Please enter your surname\n"
echo "followed by your first name: \c"
read name1 name2
echo "Welcome to Glasgow $name2 $name1"
Conditional statements
Every Unix command returns a value on exit which the shell can interrogate. This value is held in the read-only shell
variable $?. A value of 0 (zero) signifies success; anything other than 0 (zero) signifies failure.
The if statement
The if statement uses the exit status of the given command and conditionally executes the statements following. The
general syntax is:
if test
then
commands (if condition is true)
else
commands (if condition is false)
fi
then, else and fi are shell reserved words and as such are only recognised after a newline or ; (semicolon). Make sure
that you end each if construct with a fi statement. if statements may be nested:
if ...
then ...
else if ...
...
fi
fi
The elif statement can be used as shorthand for an else if statement. For example:
if ...
then ...
elif ...
...
fi
The && operator
You can use the && operator to execute a command and, if it is successful, execute the next command in the list. For
example:
cmd1 && cmd2
cmd1 is executed and its exit status examined. Only if cmd1 succeeds is cmd2 executed. This is a terse notation for:
if cmd1
then
cmd2
fi
The || operator
You can use the || operator to execute a command and, if it fails, execute the next command in the command list. For
example:
cmd1 || cmd2
cmd1 is executed and its exit status examined. If cmd1fails then cmd2 is executed. This is a terse notation for:
cmd1
if test $? -ne 0
then
cmd2
fi
Testing for files and variables with the test command
The shell uses a command called test to evaluate conditional expressions. Full details of this command can be found in the
test manual page. For example:
if test ! -f $FILE
then
if test "$WARN" = "yes"
then
echo "$FILE does not exist"
fi
fi
First, we test to see if the filename specified by the variable $FILE exists and is a regular file. If it does not then we test to
see if the variable $WARN is assigned the value yes, and if it is a message that the filename does not exist is displayed.
The case statement
case is a flow control construct that provides for multi-way branching based on patterns. Program flow is controlled on
the basis of the wordgiven. This word is compared with each pattern in order until a match is found, at which point the
associated command(s) are executed.
case word in
pattern1) command(s)
;;
pattern2) command(s)
;;
patternN) command(s)
;;
esac
When all the commands are executed control is passed to the first statement after the esac. Each list of commands must
end with a double semi-colon (;;). A command can be associated with more than one pattern. Patterns can be separated
from each other by a | symbol. For example:
case word in
pattern1|pattern2) command
... ;;
Patterns are checked for a match in the order in which they appear. A command is always carried out after the first instance
of a pattern. The * character can be used to specify a default pattern as the * character is the shell wildcard character.
The for statement
The for loop notation has the general form:
for var in list-of-words
do
commands
done
commands is a sequence of one or more commands separated by a newline or ; (semicolon). The reserved words do and
done must be preceded by a newline or ; (semicolon). Small loops can be written on a single line. For example:
for var in list; do commands; done
The while and until statements
The while statement has the general form:
while command-list1
do
command-list2
done
The commands in command-list1 are executed; and if the exit status of the last command in that list is 0 (zero), the
commands in command-list2 are executed. The sequence is repeated as long as the exit status of command-list1 is 0 (zero).
The until statement has the general form:
until command-list1
do
command-list2
done
This is identical in function to the while command except that the loop is executed as long as the exit status of command-
list1 is non-zero.
The exit status of a while/until command is the exit status of the last command executed in command-list2. If no such
command list is executed, a while/until has an exit status of 0 (zero).
The break and continue statements
It is often necessary to handle exception conditions within loops. The statements break and continue are used for this.
The break command terminates the execution of the innermost enclosing loop, causing execution to resume after the
nearest done statement. To exit from n levels, use the command:
break n
This will cause execution to resume after the done n levels up. The continue command causes execution to resume at
the while, until or for statement which begins the loop containing the continue command. You can also specify
an argument n|FR to continue which will cause execution to continue at the n|FRth enclosing loop up.
Doing arithmetic
The shell does not have any arithmetic features built in and so you have to use the expr command. Details are in the expr
manual page.
Forcing evaluation of commands
Another built-in function is eval which takes the arguments on the command line and executes them as a command. For
example:
#!/bin/sh
echo "enter a command:"
read command
eval $command
Controlling when to exit a shell script
The exit statement will exit the current shell script. It can be given a numeric argument which is the script's exit status. If
omitted the exit status of the last run command is used. 0 (zero) signifies success, non-zero signifies failure. For example:
#!/bin/sh
if [ $# -ne 2 ]
# "$#" is number of parameters- here we test
# whether it is not equal to two
then
echo "Usage $0 \<file1\> \<file2\>" # not two parameters
# so print message
exit 2 # and fail ($0 is
# name of command).
fi
...<rest of script>
This script is supposed to take two positional arguments. It will exit with status 2 (error) rather than 0 (success) if it is not
called with two parameters.
Getting further information
You can get more information from the manual page for the Bourne shell (sh).