sections in this module | City College of San Francisco - CS160B Unix/Linux Shell Scripting Module: Conditionals |
module list |
The if statement uses the exit status of a Unix command to decide whether to execute a sequence of commands:
Execution of this if statement proceeds as follows:
cmd1 is executed.
if cmd1's exit status is success (0), xxx is executed.
An example with grep shows how this works:
The first if/elif clause whose command succeeds is executed. If none succeed, the else clause is executed, if one exists.
If we execute this if statement on a file file1 that contains the single line
this line contains Susan on it
we get this output:
this line contains Susan on it
file1 did not have any lines that contained Greg
but file1 did have at least one line that contained Susan
Remember, grep outputs the lines that contain the pattern. Thus, the first line in the output above is simply the line that matched! This can be very confusing to someone using your program.
Suppose your program requires the user to provide the path to an input file. Internally, you want to make a copy of the file before working on it. You might combine the code to copy the file with a diagnostic about an incorrect filename like this:
This looks fine, but if the user makes a mistake when entering the filename, your program output looks like this:
cp: cannot access mysoucefile: No such file or directory
file 'mysoucefile' is not readable
Here, your diagnostic has been intermingled with the error message from cp! Since the user had no idea the cp command was being used, this can be very confusing, and is not professional.
Controlling the output of your commands
The purpose of placing a command in an if statement is to take some action if it succeeds (or fails). In this case, you want to suppress any error messages the command produces:
We have introduced something new here: redirecting error output. As some of you may know, error messages are not output to standard output - they are ouput to the pathway standard error. We want to suppress the error message which would normally come from cp because we are producing our own error message. We can do this by redirecting standard error to /dev/null to throw it away. To redirect standard error you place standard error's number (2) as a prefix on the redirection operator, as we did above. (We will cover these redirection operators in the next module.) You can do the same with standard output, or with both, if you don't want to see it:
In the command above, grep's output of lines that match will be suppressed, as will any message about a missing or unreadable file. If you want to be more complete in your testing so that both possibilities are covered completely, you should check the file's existence and permissions before using it. This requires using the test command, which is part of our next section:
After we discuss redirection operators in the next module, we will also learn how to output our error messages to standard error, like any standard Unix command.
Indentation
Indentation is very important to enable the reader to follow your if statements. As an example, look at the following if statements without indentation:
Without indentation, even this fairly simple sequence is much less readable than the indented version:
if test -r "$userfile" -a -f "$userfile"; thenUsing !
The ! operator appears two common places in if statement: to negate a clause of a test expression and to negate the exit status of a command. Some users find one simpler than the other. Although they have different meanings, the result can be the same.
In the example below, the user needs a writable directory. If the variable that holds the directory path does not refer to a writable directory, an error should be output and the program aborted:
This logic can be a bit difficult to understand until you get used to it. There are two conditions: the path must be a directory, and the path must be writable. Both must be true if we are to proceed. Thus, if either is not true, we must abort. Hence we must change AND to OR.
It may be simpler to write the test command to test what we want to be true, then negate the result:
Whichever of these solutions makes the most sense to you is the one you should use. Be aware, however, that the ! operator as applied to commands is not available in all Bourne-type shells.
Preview question: What is the problem with the following command? if [-f "$file" -a -r$file ]; then There
are four bugs in this sequence: two will cause syntax errors
immediately, and two are data-dependent. Can you find them? (Hint: they
are all due to spacing or quoting.)cat $file fi |
Prev | This page was made entirely with free software on linux: Kompozer and Openoffice.org |
Next |