Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [75]

By Root 993 0
the first case, test evaluates both conditions. In the second one, the shell runs the first test command, and runs the second one only if the first one was successful. In the last case, && is a shell operator, so it terminates the first test command. This command will complain that there is no terminating ] character, and exits with a failure value. Even if test were to exit successfully, the subsequent check would fail, since the shell (most likely) would not find a command named -f.

* * *

Both ksh93 and bash support a number of additional tests. More information is available in Section 14.3.2.

The POSIX algorithm for test is summarized in Table 6-7.

Table 6-7. POSIX algorithm for test

Arguments

Argument values

Result

0

Exit false (1).

1

If $1 is non-null

Exit true (0).

If $1 is null

Exit false (1).

2

If $1 is !

Negate result of single-argument test, $2.

If $1 is a unary operator

Result of the operator's test.

Anything else

Unspecified.

3

If $2 is a binary operator

Result of the operator's test.

If $1 is !

Negate result of double-argument test, $2 $3.

If $1 is ( and $3 is )

Result of single-argument test, $2 (XSI).

Anything else

Unspecified.

4

If $1 is !

Negate result of three-argument test, $2 $3 $4.

If $1 is ( and $4 is )

Result of two-argument test, $2 $3 (XSI).

Anything else

Unspecified.

> 4

Unspecified.

For portability, the POSIX standard recommends the use of shell-level tests for multiple conditions, instead of the -a and -o operators. (We also recommend this.) For example:

if [ -f "$file" ] && ! [ -w "$file" ]

then

# $file exists and is a regular file, but is not writable

echo $0: $file is not writable, giving up. >&2

exit 1

fi

There are some Section 14.1 associated with test as well:

Arguments are required

For this reason, all shell variable expansions should be quoted so that test receives an argument, even if it turns out to be the null string. For example:

if [ -f "$file" ] ... Correct

if [ -f $file ] ... Incorrect

In the second case, should $file happen to be empty, test receives one less argument than it needs, leading to strange behavior.

String comparisons are tricky

In particular, if a string value is empty, or starts with a minus, test could become confused. This leads to the rather ugly, but widespread convention of prefixing string values with the letter X. (The use of X is arbitrary, but traditional.)

if [ "X$answer" = "Xyes" ] ...

You will see this used in many shell scripts, and it is in fact used in examples throughout the POSIX standard.

The algorithm just given for test, along with always quoting all arguments, should be enough for a modern version of test, even if the first argument starts with a minus. Thus we don't see a lot of need for the leading X prefix in new programs. However, if maximal portability is more important than readability, you may wish to use it (and we do so, occasionally).

test can be fooled

When checking the access of files mounted over a network, it is possible for unusual combinations of mount options and file permissions to "fool" test into thinking that a file is readable, when in fact the operating system won't let you access the file. Thus, although:

test -r a_file && cat a_file

should always work in principle, it can fail in practice.[2] About all you can do is add another layer of defensive programming:

if test -r a_file && cat a_file

then

# cat worked, proceed on

else

# attempt to recover, issue an error message, etc.

fi

Numeric tests are integer-only

You cannot do any kind of floating-point arithmetic with test. All numeric tests work only with integers. (ksh93 understands floating-point numbers, but you can't rely on that feature for full portability.)

Example 6-1 presents an improved version of the finduser script presented in Section 2.6. This version tests $#, the number of command-line arguments, and prints an error message if exactly one isn't supplied.

Return Main Page Previous Page Next Page

®Online Book Reader