Loops
Like Bourne shell, the C shell also supports three loop structures
- The foreach loop
- The while loop
- The repeat loop
The foreach Loop
The general for of the foreach loop is as:
foreach shell_varaible (value1 value2 value3 …. )command1
command2
…. end
Here the loop control variable shell_varaible takes on in turn each value from the specified list of values and execute the same sequence of commands for each value. And this process continues until the list is emptied.
Here is the simple example of the foreach loop.
# C shell script17# Usage: csscript17
foreach day (MON TUE WED THU FRI SAT SUN)
echo $day
end
On executing this script, you get the following output….
% csscript17
MON
TUE
WED
THU
FRI
SAT
SUN
%
Here the loop control variable is day in turn takes the value in succession from the specified list (MON TUE WED THU FRI SAT SUN). Initially the day is set to ‘MON’ and the statements between foreach and end is executed. Then the day is set to next value ‘TUE’ and the echo statement is executed again.
As we have done indentation in the Bourne shell, likewise here also we have done indentation just to make it clearer to see where the loop starts and where it terminates.
Just like Bourne shell, the C shell has following techniques to provide wordlist:
- The foreach loop can take values from the shell script command line:
foreach name ($*)foreach name ($argv)
foreach name ($argv[1-5])
and so on. Recall that $* or $argv stands for command line arguments following the name of the script. The third foreach loop takes first five arguments and ignores the remaining arguments.
# C shell script18# Usage: csscript18
foreach name ($argv)
echo $name
end
Now let us see what happens when you execute this script.
% csscript18 Eyes are more accurate witness than ears.
Eyes
are
more
accurate
witness
than
ears.
%
Here the variable name takes in turn each command line argument and echo echoes its value.
- The foreach value can also take filenamesfrom a directory as values:
foreach fname (*)foreach fname (*.txt)
The first loop picks up all files from the current working directory; the second loop picks up all text files from the current working directory.
# C shell script19# Usage: csscript19
foreach filename (*)
mv $filename.txt $filename.doc
end
It would pick up all text files from current directory and make them document files
- The loop control variable can take values from a shell variable as shown below:
# C shell script20# Usage: csscript20
phrase = “Education begins with life”
foreach word ($phrase)
echo $word
end
When you execute this script, the foreach loop would become
foreach word (Education begins with life)
Here the control variable word would take values ‘Education’, ‘begins’, ‘with’ and ‘life’ in turn.
- The foreach loop can take values from the output of the command by using the back quotes ‘ ‘ command substitution as illustrated in following script.
# C shell script21# Usage: csscript21
foreach cm (‘ cat players ‘)
echo $cmd
end
Here the ‘ cat players ‘ would be replaced with the contents of file players and then the cmd would be set in turn each word in the file players.
The while Loop
The general form of the C shell is as:
while (expression)command
command
….
end
The commands within the while loop are executed till the expression results in true. When the expression becomes false, the control would automatically transfer to the first command that follows the while loop immediately.
Note that the commands within the while loop may be a single command or a set of commands. Unlike the Bourne shell, the expression is enclosed in parentheses. However there is a significant difference between the Bourne shell’s while and C shell’s while. In the Bourne shell’s while, the expression part is referred to the success or failure of command, whereas the C shell’s expression more typically is a comparison of value.
Now let us write a simple script that calculate the sum of first 50 odd numbers.
# C shell script22# Usage: csscript22
@ count=1
@ sum=0
while ( $count <= 50 )
@ sum = sum + 2 * count – 1
@ count++
end
echo The sum of first 50 odd numbers is $sum.
Here is the output of this script….
% csscript22
The sum of first 50 odd numbers is 2500
%
Here two commands are executed 50 times. Initially the variable count is set to 1 and sum to 0. In each iteration, the sum is evaluated, the value of count is incremented by one. As soon as the value of count becomes 51, the loop is terminated and the echo statement immediately echoes the value of sum.
Now let us write a program to find if a number is prime or not.
# C shell script23# Usage: csscript23
echo “Enter a number: \c”
set num = $<
@ i=2
@ flag = 1
while ($i <= $num / 2)
if ($num % $i == 0) then
@ flag = 0
break
endif
@ i++
end
if ($flag == 1) then
echo $num is a prime number.
else
echo $num is not a prime number.
endif
And here are few sample outputs….
% csscript23
Enter any number: 7
7 is a prime number.
% csscript23
Enter any number: 35
35 is not a prime number.
%
- In this program the loop continues until you type in other than a lower case ‘y’ or upper case ‘Y’. You have used the break command. The purpose of the break command in this shell is similar to the Bourne shell’s break command. It causes the loop to be exited.
- The switch statement, however, requires the use of breaksw rather than a break. The counter part of break is continue. The continue command causes the program to skip the remaining instructions in the loop and transfer the control to the beginning of the loop. Both these commands, break and continue, are associated with loops.
Now let us see another program that print even or odd numbers.
# C shell script24# Usage: csscript24
@ choice=y
while ($choice==y || $choice == Y)
echo “Enter a number: \c”
set num = $<
if ($num %2 == 0) then
echo “Even number”
else
echo “Odd number”
endif
echo “Do you want to continue \(y\n\): \c”
set $choice = $<
end
The output of this program is as….
% csscript24
Enter a number: 21
Odd number
Do you want to continue (y\n):y
Enter a number: 14
Even number
Do you want to continue (y\n):y
Enter a number: 200
Even number
Do you want to continue (y\n):n
%
All the operators of C shell are taken from the C language, except these two =~ and !~ operators. The =~ and !~ operators allow the right hand side to be a pattern using the filename metacharacters, *. ? & [ ] of the C shell.
Thus
=~ matches the string on the left side to the pattern containing *, ?. or [ ]
!~ matches the string on the left side to the pattern not containing *, ?. or [ ]
Following program illustrates such type of operators.
# C shell script25# Usage: csscript25
@ choice=y
while ($choice =~ [Yy])
echo “Enter a character: \c”
set char = $<
if ($char !~ [aeiou]) then
echo It is not a vowel
continue
else
echo It is a vowel.
Break
endif
end
The output of this program is….
% csscript25Enter a character: s
It is not a vowel
Enter a character: a
It is a vowel
%
Here the loop continues until the input matches with any character specified in the list [aeiou].
The repeat Loop
The C shell repeat loop looks like this:
repeat n command
Here the command is executed n times. The command must be a simple and single command. It may contain arguments and I/O redirection, but no pipes or set of commands.
Let us see the repeat command at command prompt.
% repeat 2 echo Great men never die.
Great men never die.
Great men never die.
%
You can also use this loop in a shell script. Here is the simple example.
# C shell script26# Usage: csscript26
echo “How many times you repeat this phrase\?”
phrase=”Glory is poison that can only be taken in small dosses.”
echo $phrase
set num = $<
repeat $num $phrase
When you execute this script, its output would be as….
% csscript26
How many times you repeat this phrase\?”
Glory is poison that can only be taken in small dosses.
4
Glory is poison that can only be taken in small dosses.
Glory is poison that can only be taken in small dosses.
Glory is poison that can only be taken in small dosses.
Glory is poison that can only be taken in small dosses.
%
Comparison of Bourne Shell and C Shell
Let us briefly summarize the differences between the Bourne shell and C shell.
|
ch |
csh |
Default Prompt |
$ |
% |
Comments |
# |
# |
Filename Expansion substitution |
? * [ ] [! ] |
? * [ ] [! ] |
System-defined Shell variables |
HOME PATH CDPATH TERM |
home path cdpath term |
I/O Redirection |
|
|
Log in files |
.profile |
.login
|
Variable Operations |
var=value var=’expr $var + 1‘ |
set var=value @ var=$var + 1 |
If statement |
if [test_expression] then Command(s) fi |
If (C_expression) then
Command(s) endif |
|
if [test_expression] then Command(s) else Command(s) fi |
if (C_expression) then
Command(s) else Command(s) endif |
|
if [test_expression] then Command(s) elif [test_expression] then Command(s) else Command(s) fi |
if (C_expression) then
Command(s) else if (C_expression) then Command(s) else Command(s) endif |
For Loop |
for var in list do Command(s) done |
foreach var (list)
Command(s) end |
While Loop |
while [test_expression] do Command(s) done |
while (C_expression)
Command(s) end |
Repeat-until Loop |
until [test_expression] do Command(s) done |
repeat n Command |
Switch-case Structure |
case value in label1) Commands(s) ;; label2) Commands(s) ;; *) Commands(s) ;; esac
|
switch (value) case choice1: Commands(s) breaksw case choice1: Commands(s) Breaksw default: Commands(s) breaksw endsw |