Shell Script Programming
{LANG_NAVORIGIN} Operating System Linux
Colin Sauze
07/02/2005
Loops
Programs often need to repeat the same code over and over again, instead of constantly rewriting code we can have what are known as loops. This allows us to repeat code a specified number of times, until a certain condition is met or if needed indefinitely.
The first kind of loop we'll look at is called a for loop and is used to repeat an action a given number of times. For loops in bash work by taking a name of a variable and a series of inputs, each time round the loop the value of the variable is set to the next value in the list of inputs. The syntax is for
variablename in
inputlist this must be followed by a do statement in the same way an if statement must be followed by a then statement. The following code is then executed each time round the loop, the end of the loop is specified by a done statement in the same way an if statement is ended with an fi statement. Here's an example which loops round the numbers 1 to 5. The variablename must NOT be preceded by a $ symbol here, common practice amongst programmers is that variable names i, j and k are used in for loops. Each value in the input list must be separated by a space, the list can be made up with a variable or the output from a command surrounded by backtics (` symbols).
#!/bin/bash
for i in 1 2 3 4 5 ; do
echo $i
done
This script will output 1, 2, 3, 4,5 each on separate lines.
Instead of writing out endless lists of numbers for loops which need numbers there is a program called “seq” which will generate these numbers for us. Seq can either take 1 parameter where it will output numbers up to and including that value, 2 parameters to specify start and stop values or 3 parameters to specify the start value, increment and stop value. You can use negative number if you wish.
#!/bin/bash
for i in `seq 1 5` ; do
echo $i
done
This does exactly what the first example did but using seq.
There is another type of loop called a while loop, this will execute until a given condition is met. Its syntax is while [
condition ] followed by a do statement, the code for the loop and then a done statement. The condition takes the same format as an if statement, as long as the statement evaluates to true the loop will continue running.
Here's an example.
#!/bin/bash
A=”1”
while [ “$A” -lt “5” ] ; do
A=$[$A + 1]
echo $A
done
This example adds one to the value of A each time it goes round the loop as long as A is less than 5.
Sometimes a program needs to run forever (or until the user stops it). This can be done by specifying a condition that will always be true such as [ “0” = “0” ] or [ “$A” = “$A”]. Such programs can slow the computer down a lot and it may be advisable to make the script sleep for a little while each time it goes round the loop. This is done simply by writing sleep followed by a time in seconds.
This example will display the current time and date using the date command every second until you stop it (press Control and C at the same time).
You can break out of a loop if you feel the need (like an endless loop you've discovered you need to exit) by simply writing the command break, this will usually be done from within an if statement.
#!/bin/bash
while [ “0” = “0” ] ; do
A = $[ $A + 1]
date
sleep 1
if [ “$A” - gt “10000” ] ; then
break
fi
done
This loop will stop running when A hits 10000.
Terminating Scripts
You can exit a script at any time by simply writing “exit”. If you add a value afterwards this is sent as a return value and can be used by the program which started the script to gain some insight as to whether the script functioned properly or not. A 0 normally indicates it did, non 0 indicates something went wrong. Just writing exit on its own will is the same as writing exit 0.
Functions
The need often arises to execute the same piece of code all across your script. One solution to this is to rewrite the same code all over your script but this means if you need to change something you have to change every copy. Instead you can use functions (also known as sub routines) to contain bits of code you often need to execute. Functions are specified by writing a function name followed by a {, then the code for this function and finally a } symbol to indicate the end of the function. Functions are invoked by simply writing their name out. You can pass parameters to a function like you can to a script by putting the parameter values after the function name, the function can access these using $1, $2 etc variables like a script can get access to its parameters. Any variable which is created outside the function can be access by the script, but any variable it creates cannot be. It is possible for one function to call another, its even possible for it to call itself! A function calling itself is known as recursion, a full explanation of recursion and its benefits is beyond the scope of this series (hint: its used for things like calculating factorials where you multiply a number with every number less than it and greater than 1, e.g. 4 factorial is 1*2*3*4).
#!/bin/bash
B=”2”
testfunction
{
echo $1
B=$[ $1 + 1 ]
C=$[$1 + 2]
}
testfunction $B
echo $B
Here we call testfunction which add's 1 to $1 and sets B to this value and then adds 2 to $1 and sets C to this value. The modified B will be available outside the function, but C won't be as it is created by the function.
Performing arithmetic
There are 3 ways arithmetic can be performed in bash scripts. With all 3 methods standard mathematical precedence takes place (remember BODMAS or Brackets, Operation, Division, Multiplication, Addition Subtraction from school??).
The simplest way is to place the arithmetic expression in between a “$[“ and a “]”, you may then assign a variable to this value. You may substitute variable names for numbers, if the variables aren't numbers an error will occur and your script will exit.
#!/bin/sh
X=”5”
Y=”2”
echo $[ $X * $Y ]
This method only works in bash, it doesn't work in the older bourne shell which is the default on many commercial Unix systems like HP Tru64, HP-UX, SunOS, Solaris, IBM AIX etc. If you’re using old bourne shell there is no built in support for arithmetic and you must use the external programs expr or bc. Expr is intended for use in shell scripts and provides a way of doing simple arithmetic, you may find (depending on which version of Unix you use) that it doesn't like large numbers (over 32767), in these cases you'll have to use bc a command line calculator.
| Operator | Purpose |
| + | Addition |
| - | Subtraction |
| / | Division |
| * | Multiplication |
| % | Modulus (remainder from a division operation) |
| ( and ) | Precedence over rides |
The standard mathematical operators, these are the same using all 3 methods of arithmetic and are also the same in virtually all programming languages.
Expr has some other peculiarities, you can't use * without it giving an error, you must put a “” in front of the *. “” has a special meaning in shell scripts and it is called an escape character, anytime you see a “” in front of a character it stops the shell interpreting the character after. In this case its needed as * has other meanings in shell scripts. More will be explained on escape characters in part 3.
#!/bin/sh
X=”5”
Y=”2”
echo `expr $X * $Y`
Bc is a much more powerful than expr but must be invoked slightly differently. What you have to do is send the expression you want to calculate to bc in a pipe, this is usually from the echo program.
Here's an example for adding 1 and 2:
#!/bin/sh
echo “1 + 2” | bc
References:
http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html – A beginners introduction to bash programming, covers similar topics to this tutorial, useful for extra examples also a bit more detailed.
http://www.tldp.org/LDP/Bash-Beginners-Guide/html/index.html – Another beginners guide to bash, with a lot more detail and lots of coverage of external programs to help you. This tutorial also covers material mentioned in this entire series.
http://nl.ijs.si/GNUsl/tex/tunix/tips/tips.html – Unix Tips and Tricks, a large guide to the Unix command line in general and how to perform all sorts of things with it. Some of the commands referenced in it are explained in more detail in part 3.
E-Mail Link
Your IP address will be sent with this e-mail