Bourne tutorial



Yüklə 478,18 Kb.
Pdf görüntüsü
səhifə16/20
tarix08.10.2017
ölçüsü478,18 Kb.
#3721
1   ...   12   13   14   15   16   17   18   19   20

echo all tests fail

fi

fi



Some times you want to perform a test if the condition is false. You might try the following, but a

syntax error would exist:

if condition

then


# ignore this

else


echo condition is false

fi

The "if," "then" and "else" statements must be followed by a list. A comment is not a list. There must



be a command. In this case, the ":" command, which does nothing, can be used:

if condition; then :; else

echo condition is false

fi

You may notice how I vary the indentation style. Any form is correct. Pick the one you are more



comfortable with. As an aside, the C shell will allow a comment as the only statement inside a

conditional block.

While - loop while true

The "if" test is performed once. If you want to loop while a test is true, then use the "while" command:

while mytest

do

echo mytest is still true



done;

The "while" command is useful in reading input, combined with the "read" command, which reads

standard input, assigns the words seen to its arguments, and returns 0, or false, when the end of file is

reached. The following, therefore, echoes every line:

while read a

do

echo $a



done

This can be used to ask for a list of arguments:

echo "Please type the arguments"

echo "Type Control-D (EOF) when done"

args="":

echo '?'


while read a

do

args="$args $a"



echo '?'

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

44 of 66


11/21/2011 12:03 PM


done

echo "The arguments are $args"

A lot of people forget a list follows the "while" command. They assume a single command must follow

the "while" keyword. Not true. The above fragment could be written:

echo "Please type the arguments"

echo "Type Control-D (EOF) when done"

args="":

while


echo '?'

read a


do

args="$args $a"

done

echo "The arguments are $args"



This places the prompt right before the query, which is good programming style. The "while" command

can be combined with input redirection

cat file | while read a

do

file contains line $a



done

The "while" command can get its input from a subshell, and be placed inside a subshell. The following

script

#!/bin/sh



(echo a b c;echo 1 2 3) | (while read a; do

echo $a $a

echo $a $a

done


) | tr a-z A-Z

generates the following output:

A B C A B C

A B C A B C

1 2 3 1 2 3

1 2 3 1 2 3

The following also works:

while read a

do

echo a=$a



done 

The C shell doesn't allow this flexibility in redirecting standard input.

There are a few subtle points about the "read" and "while" commands. The following is a syntax error:

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

45 of 66


11/21/2011 12:03 PM


while true

do

# comment



done

There must be a command in the list between the ""do" and "done" commands. The null command ":"

will fix the syntax error:

while true

do

:

done



I expected

echo 1 2 3 | read a; echo a is $a

to work, but it doesn't. At least on the systems I tried, it doesn't work. However, the following does:

echo 1 2 3 | ( read a; echo a is $a )

The following seems strange, but does work:

read a ;echo a is $a

read a ;echo a is $a

read a ;echo a is $a

)

as does:


( read a ;echo a is $a

read a ;echo a is $a

read a ;echo a is $a


Exactly three lines of the file are read. I should emphasize the that C shell cannot do this easily. It does

not have a built-in mechanism to read exact one line. Also the C shell command to read a single line

only reads from the controlling terminal, and cannot be redirected to get input from a file, or a pipe,

while the Bourne shell can.

What happens if the "read" command has more than one argument? The command breaks the input line

into words, using whitespace as the characters between words. Each word is assigned to a different

variables. If there are not enough words, the last variables are assigned an empty value. If there are too

many, the last variable gets the leftovers. What gets printed if the following is executed?

echo 1 2 3 4 5 | (

read a b c

echo first $a

echo second $b

echo third $c

)

Bourne Shell Tutorial



http://www.grymoire.com/Unix/Sh.html

46 of 66


11/21/2011 12:03 PM


The first variable is "1," the second is "2," and the last is "3 4 5."

Together, these two commands provide a lot of flexibility, more so than what appears on the surface.

If you want to loop forever, you could do what most people do:

while true

do

echo never stop



done

This executes the empty script "true." Another way to do the same, without needing to execute another

process, is to use the ":" command:

while :


do

echo never stop

done

Until - loop until true



The until command acts the same as the "while" command, except the test is inverted.

until testa

do

echo not yet



done

will echo "not yet" until "testa" becomes true (exits with a status of zero).

Next, the "for" and "case" commands.

Bourne Shell Flow Control Commands

I previously discussed the Bourne Shell commands "if," "while" and "until." Next I will discuss the

other two commands used for controlling flow -- "for" and "case." The templates for these commands

are:

for name do list done



for name in word ... do list done

case word in esac

case word in pattern ) list;; esac

case word in pattern | pattern ) list;; esac

For - Repeating while changing a variable

The "for" command executes the commands in a list, but changes the value of a variable for each loop.

To illustrate, the command

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

47 of 66


11/21/2011 12:03 PM


Yüklə 478,18 Kb.

Dostları ilə paylaş:
1   ...   12   13   14   15   16   17   18   19   20




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©www.genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə