• No results found

The test Command

In document Hp-Ux Unix Rehman (Page 126-135)

Table 6-2. Meta Characters Used in Regular Expressions Charact

Chapter 7. File Permissions Chapter Syllabus

10.6 The test Command

Branching decisions are made depending on the result of a test command. The test command can perform tests on numeric and string data as well as on files. The test command returns a true or false value. The true value is always zero, while false is a number other than zero.

Usually this number is one. You can check the result code of the test command to make a branching decision. The test command can be used in explicit or implicit modes. In the explicit mode, the test command is used as follows.

$ test "ABC" = "abc"

In the implicit mode, the word "test" is not there; square brackets are used instead.

$ [ "ABC" = "abc" ]

The command does not print anything on the terminal screen. The result code can be checked using the $? variable as explained earlier in the chapter.

Testing Numeric Values

Tests can be performed to compare two or more integers. The relations that can be used with numeric data are shown in Table 10-3.

Table 10-3. Numeric Tests

Relation Description

-eq Equality check

-ne Not equal

-lt Less than

-gt Greater than

-le Less than or equal to

-ge Greater than or equal to

Numeric testing will be used in shell programs later in this chapter.

Testing String Values

The string values can be checked for equality and nonequality. Other than that, a single string can be tested if it has a zero length or not. The string operations are shown in Table 10-4.

Table 10-4. String Tests

Operation Description

string1 = string2 True if string1 and string2 are equal

string1 != string2 True if string1 is not equal to string2 -z string True if string length is zero

-n string True if string length is nonzero string True if string length is nonzero

Testing Files

Testing on files can be performed in many ways. Some of these are shown in Table 10-5. A list of other supported file tests can be found using the man sh-posix command.

Table 10-5. File Tests

Operation Description

-d file True if the file is a directory

-f file True if the file exists and is a normal file (not a directory) -s file True if the file is more than zero bytes in length

-r file True if the file is readable -w file True if the file is writable -e file True if the file exists

-L file True if the file is a symbolic link file1 -nt file2 True if file1 is newer than file2 file1 -ot file2 True if file1 is older than file2 -x file True if the file is executable

For example, if file file1 exists, and you use the following command to check its existence, you will get an exit code of zero (true).

$ [ -f file1 ]

$

$ echo $?

0

$

Testing with Logical Operators

Logical operations can be performed on two expressions with one of the logical operators shown in Table 10-6.

Table 10-6. Logical Operators

Operation Description

expr1 -o expr2 Logical OR, true if either expr1 or expr2 is true expr1 -a expr2 Logical AND, true if both expr1 and expr2 are true

! expr Logical NOT, true if expr is false

The following code segment tests files represented by the first two command line arguments and prints a message if both files exist.

#!/usr/bin/sh if [ -f $1 -a -f $2 ] then

echo "Test successful"

fi

10.7 Branching

Two types of branching are used in shell programming. One of these is represented by the if structure and the other one by the case structure. In this section, you will learn how to use both of these branches. You will also find some useful examples of shell programs.

The if-then-fi Structure

The if-then-fi structure is used to check a condition with the help of a test command. If the test returns a true value, then an action is performed. If the test returns a false value (not true), the action part of the program is not executed. The general syntax of this structure is as follows.

if expr then action fi

where expr is a test performed on some variables or constants. The action is a set of one or more commands that are executed if the test returned a true value. This is shown in Figure 10-1 using a flow diagram.

Figure 10-1. The if-then-fi structure.

Previously you have seen how to check the number of arguments on the command line. You can write a shell program to check the number of arguments and print an error message if there is no argument on the command line. The program script-08 does the same thing and is listed here using the cat command.

$ cat script-08

#!/usr/bin/sh if [ "$#" -lt 1 ] then

echo "Error: No arguments provided on command line"

exit 3 fi

echo "Program terminated normally"

$

When you execute this program without any command line argument, you will see the following message on your screen.

Error: No arguments provided on command line

If you check the return code using the echo $? command, a value of 3 will appear. On the other hand, if you provide at least one argument on the command line, the return code will be zero and the message on your screen will be:

Program terminated normally

This is a useful way of checking the number of command line arguments if your program expects a fixed number of arguments. For example, the cp command requires two command line arguments showing the source and destination paths of the file being copied. If you don't provide two arguments, the command prints an error message.

The if-then-else-fi Structure

This structure is used when you want to perform one of two actions, depending on the result of a test. The general syntax of the structure is:

if expr then action1 else action2 fi

If the result of expr is true, action1 is performed. In the other case, action2 is performed. Each of action1 and action2 may be a set of one or more commands. The flow chart of this structure is shown in Figure 10-2.

Figure 10-2. The if-then-else-fi structure.

You can modify script-08 so that it accepts two file names as argument and copies the first file to the second file. If there are not exactly two arguments, it tells you that you did not provide two arguments. It then displays all of the arguments it received from the command line. The modified form is script-09.

#!/usr/bin/sh if [ "$#" -eq 2 ] then

cp $1 $2 else

echo "You did not provide two arguments."

echo "The arguments provided are $*"

fi

echo "Program terminated"

This program works fine, but it does not incorporate any facility for dealing with a problem. The next program, script-10, is a more sophisticated shell program that performs a number of checks before copying one file to another. It first checks the number of arguments, and if you have not provided two arguments, it terminates at that point. Then it checks if the source and destination files are the same. If they are, it terminates at this point. The next check is to verify that the source file exists and that it is not a special file. After that, it checks if the source file exists and is readable. If both of the conditions are true, it checks the destination file. If the destination file already exists, it asks if you want to overwrite it. If you say "yes," it copies the source file to the destination; otherwise it terminates. If the destination file does not exist, it copies the source to the destination without interacting with you.

#!/usr/bin/sh if [ "$#" -ne 2 ] then

echo "You have not provided exactly two arguments."

exit 1 fi

if [ "$1" = "$2" ] then

echo "Source and destination names are the same."

exit 1 fi

if [ ! -f "$1" ] then

echo "File $1 does not exist or not a regular file."

exit 2 fi

if [ ! -r "$1" ] then

echo "File $1 is not readable."

exit 3 fi

if [ -f $2 ] then

echo "File $2 already exists. Do you want"

echo "to overwrite (yes/no): \c"

read ANSWER

if [ "$ANSWER" = "yes" ] then

cp $1 $2

echo "File copied"

exit 0 else

echo "File not copied"

exit 4 fi fi

cp $1 $2

echo "File copied"

The exit status is different at every point so that you may come to know at what stage the program terminated by checking the exit code. You can use this program in place of the standard cp command as it is safer and does not overwrite existing files without notification.

The case Structure

The case structure is used where you want to branch to multiple program segments depending on the value of a variable. The general syntax of the case structure is:

case var in pattern1) commands ;;

pattern2) commands ;;

… patternn) commands

;;

*)

commands ;;

esac

The value of var is checked. If this is equal to pattern1, the commands in the first block are executed. The first block ends at the ;; pattern. If the value of var matches pattern2, the commands in the second block are executed. If var matches none of the pattern values, the commands in the last block after "*)" are executed. This last part is optional and can be omitted. The case statement is shown in the flow diagram of Figure 10-3.

Figure 10-3. The case structure.

Program script-11 is used as an example here. It provides you with a few choices. If you select one of these, appropriate action is taken.

#!/usr/bin/sh

echo "Press w to list users"

echo "Press d to see date and time"

echo "Press p to see current directory"

echo

echo "Enter your choice: \c"

read VAR case $VAR in w|W) who ;;

d|D) date ;;

p|P) pwd ;;

*) echo "You have not pressed a valid key"

esac

echo "The case structure finished"

For example, if you press "w" or "W", the list of users currently logged into the system is displayed. Note that the "|" character is used for the logical OR operation in the case structure.

If you make a choice that is not valid, the last part of the case structure is executed, which shows that you need to make a valid choice. Wildcard and range characters (*, ?, [ ]) can also be used in patterns to be matched.

Chapter Summary

This was an introductory chapter on shell programming, where you studied what a shell program looks like and how to write shell programs. The first line of the shell script is used to determine which subshell will be invoked for the execution of the program. Comments are used in the shell programs with the help of the "#" character, such that anything that follows this character is considered a comment. Then you learned how to debug a program using the -x option. Ne-xt was the use of variables in shell programs. Environment variables can be read in a shell program. Any change to environment variables is lost as soon as the program finishes its execution.

Command line arguments are stored in special variables whose names range from $0 to $9.

Above $9, use braces to enclose the argument number. For example, ${12} would be the twelfth command line argument. The $0 variable shows the name of the program itself, and the

rest keep values of other command line parameters. These command line parameters can be shifted left with the use of the shift command.

Interactive programs can be written with the help of the read command. This command takes input from the user at run time and stores it in a variable. The echo command is used to print something on the user terminal. It uses escape characters to format the printed data. You learned about the exit command and exit codes that show termination status of a program.

To make a conditional branch, you need to test a condition. The test command is used for this purpose, and you learned implicit and explicit use of this command. In the last part of the chapter, three branch structures were presented. The first one was the if-then-fi structure, the second was the if-then-else-fi structure, and the third one was the case structure. The if-then-fi structure is used for executing a block of commands if the result of a test is true. Its syntax is as shown here.

if expr then action fi

The if-then-else-fi structure is used to make either one or the other choice of the two available options. Its syntax is:

if expr then action1 else action2 fi

The case structure is used to select one of many options available. The general format of the case structure is:

case var in pattern 1) commands ;;

pattern 2) commands ;;

...

pattern n) commands ;;

*)

commands ;;

esac

In the next chapter, you will learn about use of loops and some more features of shell programming.

Chapter Review Questions

1: What problem may arise if you don't provide the shell name inside a program?

2: Is it necessary to make a file containing a shell program executable?

3: Create a shell program that reads three command line arguments and then prints these in reverse order.

4: What is the importance of exit codes?

5: Write a shell program that uses the test command in explicit mode to check if the first and second

command line arguments have the same value.

6: What is the major difference between the if and case structures?

Test Your Knowledge

1: You create a shell program and save it into a file with name "more". Your current

directory name is included in the PATH variable at the end. When you run this program by typing "more", nothing happens and the cursor just stops at the next line. What may be the problem?

You have written some commands in the program that the shell does not understand.

The shell program file is not executable.

You have used a program name that matches a standard HP-UX command.

There is a problem with your terminal and you need to reset it.

2: What is true about variables used in shell programs?

Variables starting with letters can be used in programs.

Values of variables can be changed in the programs.

The shell can read and modify environment variables for its own use.

All of the above.

3: You use the echo $? command. The result is 2. What do you conclude from this?

The echo command printed the number of characters in its first argument.

The last command terminated abnormally.

The "?" symbol has an ASCII value equal to 2.

None of the above.

4: You used shift 3 in your shell program. What will be its effect?

It will shift the first three command line arguments to the left.

It will shift the last three command line arguments to the left.

It will shift all command line arguments by three places toward the left.

It will shift all command line arguments by three places toward the right.

5: What does the echo "\a" command do?

It prints the character a.

It prints the character \a.

It prints a hexadecimal character "a" that represents decimal 10.

It gives a beep sound.

6: What is wrong with the command [ "ABC" -eq "ABC" ]?

You are comparing strings with a numeric operator.

The same string is used on both sides of the operator.

The quotation marks are not needed here.

Parentheses should be used instead of square brackets.

7: A shell script with the name myscript does not have the execution bit set. How can you execute it?

exec myscript sh myscript run myscript

No shell script can be executed until its execution bit is set.

8: How can you list all command line arguments?

using $*

using $#

using the shift command using the list command

9: The true return value of the test command is:

1 0

any positive number

any number not equal to zero

10: You have a shell script as shown here. What will be the result when it is executed?

#!/usr/bin/sh ABC=aac case $ABC in a) echo "First"

;;

[aa]c) echo "Second"

;;

a*) echo "Third"

;;

*) echo "Last"

;;

esac

First Second Third Last

Chapter Syllabus

11.1 Arithmetic and Logic Operations

In document Hp-Ux Unix Rehman (Page 126-135)