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
Dostları ilə paylaş: |