Linux Training

Linux training for private, public & voluntary sector.

0800 024 8425

City LinUX Training Courses

Section 14.
Shell programming 3
.


"The most effective debugging tool is still careful thought, coupled with judiciously placed print statements."

Brian W Kernighan in the paper Unix for Beginners 1979.

14. Shell programming 3.

14.1. Looping constructs.

Bash supports the looping flow controls for, select, case, while/ until and if.

NB. wherever a ";" appears in the description of a command’s syntax it may be replaced with one or more newlines.

14.2. For

for name [[ in [ word... ]]; do list; done

The list of words following in is expanded, generating a list of items. The variable name is set to each element of this list in turn, and list is executed each time. If the in word is omitted, the for command executes list once for each positional parameter that is set. The return status is the exit status of the last command that executes. If the expansion of the items following in results in an empty list, no commands are executed, and the return status is 0.

E.g.

sa101$ cd eg;ls -l
total 4
drwx------ 2 fulford fulford 4096 Nov 26 10:51 d
-rw-r--r-- 2 fulford fulford    0 Nov 26 10:58 f1
-rw-r--r-- 2 fulford fulford    0 Nov 26 10:58 f2
lrwxrwxrwx 1 fulford fulford    2 Nov 26 10:49 f3 -> f1
sa101$ cat >movefiles
#!/bin/sh
for file in f*;do
     if [ -f $file ];then
          mv $file d
     fi
done
^d
sa101$ chmod 755 movefiles
sa101$ ./movefiles
sa101$ ls
d  f3
sa101$ ls -l d
total 4
-rw-r--r-- 2 fulford fulford 0 Nov 25 21:25 f1
-rw-r--r-- 2 fulford fulford 0 Nov 25 21:25 f2
-rw-r--r-- 1 fulford fulford 9 Nov 25 10:51 file1
sa101$ ls -l
total 4
drwx------ 2 fulford fulford 4096 Nov 26 10:51 d
lrwxrwxrwx 1 fulford fulford    2 Nov 26 10:49 f3 -> f1

Note that the symbolic link file f3 now points to a none existent f1 in the current directory.

14.3. Select.

select name [ in word ... ] ; do list ; done

The list of words following in is expanded, generating a list of items. The set of expanded words is printed on the standard error, each preceded by a number. If the in word is omitted, the positional parameters are printed.

The PS3 prompt is then displayed and a line read from the standard input. If the line consists of a number corresponding to one of the displayed words, then the value of name is set to that word. If the line is empty, the words and prompt are displayed again. If EOF is read, the command completes. Any other value read causes name to be set to null. The line read is saved in the variable REPLY. The list is executed after each selection until a break command is executed.

The exit status of select is the exit status of the last command executed in list, or zero if no commands were executed.

E.g.

sa101$ pwd
/fulford/sa101
sa101$ cd eg
sa101$ ls
d  f1  f2  f3
sa101$ cat >f3
A text file accessed by a symbolic link.
^d
sa101$ select file in *;do head $file;done
1) d
2) f1
3) f2
4) f3
#? 4
A text file accessed by a symbolic link.
#?
^d

14.4. Case.

case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

A case command first expands word and tries to match it against each pattern in turn, using the same matching rules as for pathname expansion. The word is expanded using tilde expansion, parameter and variable expansion, arithmetic substitution, command substitution, process substitution and quote removal. Each pattern examined is expanded using tilde expansion, parameter and variable expansion, arithmetic substitution, command substitution, and process substitution. If the shell option nocasematch is enabled, the match is performed without regard to the case of alphabetic characters. When a match is found, the corresponding list is executed. If the ;; operator is used, no subsequent matches are attempted after the first pattern match.

Using ;& in place of ;; causes execution to continue with the list associated with the next set of patterns. Using ;;& in place of ;; causes the shell to test the next pattern list in the statement, if any, and execute any associated list on a successful match. The exit status is zero if no pattern matches. Otherwise, it is the exit status of the last command executed in list. E.g.

sa101$ cat eg_select.sh
#!/usr/bin/bash
select colour in red amber green ;do
     case $colour in
          green) echo "total fat <= 3%";;
          red) echo "total fat > 3% < 0%";;
          amber) echo "total fat => 20% " ;;
     esac
done

14.5. If.

if list; then list; [ elif list; then list; ] ... [ else list; ] fi

The if list is executed. If its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, and if its exit status is zero, the corresponding then list is executed and the command completes. Otherwise, the else list is executed, if present. The exit status is the exit status of the last command executed, or zero if no condition tested true.

E.g.

sa101$ cat autofs-chk
#!/usr/bin/bash
# name     :autofs-chk
##########################################################
file=/var/run/autofs-running
if [ -f $file ];then
        pid=$(<$file)
     echo "automounter last started with pid $pid"
     exit 0
else
        echo "$0: can’t find $file. Perhaps autofs not started." >&2
     exit 1
fi


# NB. root privileges will be need to access /var/run/autofs-running

14.6. While.

while list; do list; done
until
list; do list; done

The while command continuously executes the do longlistas the last command in anlistreturns until command is identical to the while command, except that the test is negated; the do list is executed as long as the last command in alistreturns of the while and until commands is the exit status of the last do list command executed, or zero if none was executed.

E.g.

The next script looks for the directories d00, d01, d02 and d03 and creates any that are missing.

sa101$ cat msngdir
#!/usr/bin/bash
# release          : 1.2
# filename         : msngdir
# author           : fulford
#
########################################################
n=0
dir=../eg
while [ ‘find $dir -name d0\? -type d| wc -l‘ -lt 4 ]; do
      [ -d $dir/d0$n ] || mkdir $dir/d0$n
      n=‘expr $n + 1‘
      read
done
ls -l $dir

14.7. On line examples.

There are available on line a number of administrative shell scripts by the author. These scripts do not directly relate to this course but may well be found useful when looking for particular scripting techniques.

The scripts may be found at http://www.citylinux.com/linux/scripts/scripts.php .

14.8. Exercises

for:

Write a bash shell script using the for loop to take a list of five workspaces or directory names, check if they exist off the current directory and create those that do not. After each directory is created make it the current working directory and touch a file named "done" before returning to your starting directory.

Put the five directory names in a file called dirs, before you start scripting.

select;

Write a bash shell script to present 3 numbered menu options. Offer comments to the user on the validity of their choices. Include a option to end the current session without using end of input.

case;

Use the case statement in a script that can be called with the following option flags.

Image imgs/sa101-21.png

if:

Write a shell script that searches /var/log for files larger than 10MB which have not been modified for more than 30 days. If no files are found write an error message to stderr.

while

Rewrite the case script above using while to test for remaining positional parameters until all have been processed.

Using the next tools and metanotation table revise the material covered on the course so far.

14.9. Tools and metanotation:

Image imgs/sa101-22.png

 


The layout and associated style sheets for this page are taken from the World Wide Web Consortium and used here under the W3C software licence.