The POSIX shell built-in test is used to check whether specific conditions are satisfied. Such conditions may be:
file attributes,
characteristics and comparisons of strings, and
algebraic comparisons of integers.
Conditions can be negated and several conditions may be combined with one another.
Depending on the exit status, you can execute various commands, terminate loops, etc.
The POSIX shell built-in test has two forms (see syntax below). The effect is the same in both cases.
Syntax
test expression |
[ expression ] |
The square brackets as well as the delimiting blanks before and after expression are
One or more primary expressions which may be combined (see the section “Combining conditions”). |
test checks the following conditions: File attributes
(read) true if file exists and you have read permission.
(write) true if file exists and you have write permission.
(execute) true if file exists and you have execute permission.
(file) true if file exists and is a regular file.
(directory) true if file exists and is a directory.
true if file exists.
true if file exists and is a symbolic link. Normally symbolic links are followed by all other conditions.
(character device) true if file exists and is a character special file.
(block device) true if file exists and is a block special file.
(pipe) true if file exists and is a named pipe (FIFO).
(set user ID) true if file exists and its set-user-id bit is set.
(set group ID) true if file exists and its set-group-id bit is set.
(sticky bit) true if file exists and its sticky bit is set.
(size) true if file exists and is not empty.
(terminal) true if the specified file descriptor is open and assigned to a terminal. filedescr not specified:
Name of the file or directory whose attributes are to be tested. Relative or absolute path names may also be specified. If you specify the null string for file, i.e. a pair of single quotes ’’ or double quotes "", test interprets file as the name of your current directory. If you do not specify file, test issues an error message and terminates with exit status 1. A shell parameter may also be specified for file. This parameter should always be enclosed in double quotes "...". If the corresponding shell variable has not been defined, the null string will be passed as an argument to test. The quotes thus guarantee that test is always supplied an argument during parameter substitution. |
Characteristics and comparisons of stringsAny arbitrary sequence of characters may be specified as a string. Blanks and tabs included in the string must be escaped. If the string is to be protected from interpretation by the shell, the relevant metacharacters can be escaped by preceding them with a backslash \ or by enclosing the entire string within single or double quotes. The null string can be specified by a pair of consecutive double quotes or single quotes. If you do not specify a string, test issues an error message and terminates with exit status 1. A shell parameter may also be specified as a string. This parameter should always be enclosed in double quotes. If the corresponding shell variable has not been defined, the null string will be passed as an argument to test. The double quotes thus guarantee that test is always supplied an argument during parameter substitution.
(non zero) true if the specified string is not the null string, i.e. has a non-zero length.This option allows you to test whether there is a value assigned to a shell variable. The corresponding shell parameter must be enclosed within double quotes. -n not specified:
(zero) true if the specified string is the null string, i.e. has a length of zero.
True if the two strings are identical. The blanks before and after the equals sign are mandatory, since test expects this character as an independent argument. If you are comparing shell parameters, they should be enclosed within double quotes.
True if the two specified strings are not identical. The blanks surrounding the != (not equal to) sign are required, since test expects this character as an independent argument. If shell parameters are being compared, they must be quoted.
True if If
True if string is not the null string. |
Algebraic comparison of integersIntegers can either be specified directly or as values of shell variables. There is no limit to the size of integer values you can specify, nor to the size of values you can define for a shell variable.
The two integers int1 and int2 are algebraically compared by test on the basis of the operator specified in op. op can be any of the following:
(eq - equal) true if the two integers are algebraically equal.
(ne - not equal) true if the two integers are algebraically not equal.
(ge - greater than or equal) true if int1 is algebraically greater than or equal to int2.
(gt - greater than) true if int1 is algebraically greater than int2.
(le - less than or equal) true if int1 is algebraically less than or equal to int2.
(lt - less than) true if int1 is algebraically less than int2. |
Negating conditions
True if the specified condition is not satisfied. The exclamation mark must be followed by a blank. Example
test returns an exit status of 0 (i.e. true) if you are not permitted to read the specified file. |
Combining conditionsPrimary conditions can be linked with one another to form a compound expression. The condition itself can also be negated. The find command searches directories for files that satisfy given conditions. Conditions for test are combined in a similar way. The following operators can be used to combine conditions:
(and) Logical AND operator, i.e true if all conditions combined in this way are satisfied. Each -a operator must be preceded and followed by a blank.
(or) Logical OR operator, i.e true if at least one of the conditions is satisfied. Each -o operator must be preceded and followed by a blank.
compexpr represents a compound expression comprising two or more arbitrarily grouped conditions. The operator that precedes conditions grouped within parentheses applies to the whole compound expression (i.e. all conditions) and not just to the condition that immediately follows it. Example
The expression within parentheses is true if you have read or write permission for the specified file. The negation operator (!) negates the whole expression. Thus, if you have neither read nor write permission for the specified file, test will return an exit status of zero (true). |
Precedence of operatorsThe order of precedence for operators used with test is as follows: Parentheses over negation over AND over OR. The conditions within parentheses in the preceding example are thus evaluated first and then negated. |
Exit status
0 | If the specified expression is true. |
1 | Although the specified expression is syntactically correct, its evaluation returns the value false. Alternatively, you have not entered an expression. |
>1 | Error (e.g. syntactically incorrect expression). |
Error
This error message is issued if you have failed to specify a condition fully, i.e. if a file, string, or number is missing in the specification. |
Locale
The following environment variables affect the execution of test: LANG Provide a default value for the internationalization variables that are unset or null. If LANG is unset of null, the corresponding value from the implementation-specific default locale will be used. If any of the internationalization variables contains an invalid setting, the utility will behave as if none of the variables had been defined. LC_ALL If set to a non-empty string value, override the values of all the other internationalization variables. LC_CTYPE Determine the locale for the interpretation of sequences of bytes of text data as characters (for example, single- as opposed to multi-byte characters in arguments and input files), the classification of characters as upper- to lower-case, and the mapping of characters from one case to the other. LC_MESSAGES Determine the locale that should be used to affect the format and contents of diagnostic messages written to standard error. NLSPATH Determine the location of message catalogs for the processing of LC_MESSAGES. |
Example 1
The following shell script tests whether the specified positional parameter is the name of a file or of a directory. if test -f "$1" # or: if [ -f "$1" ] then echo $1 is a file elif test -d "$1" # or: elif [ -d "$1" ] then echo $1 is a directory fi Since the $1 positional parameter has been quoted, test substitutes the current directory for it if you call the shell script without further arguments. |
Example 2
The following script makes use of the operator -gt to test whether the first file specified in the command line, i.e. $1, contains more lines than the one specified after it ($2): if [ `wc -l "$1"` -gt `wc -l "$2"` ] then echo $1 contains more lines than $2 fi cat passes on the contents of the file as input for the wc -l command via a pipe. The wc -l command counts and outputs the number of lines in each of the two files. The shell substitutes the specification in the backquotes for the appropriate number of lines. |
Example 3
A test is to be performed to check whether a value has been assigned to the shell variable TAPE. This can be done in various ways: Method A if [ ! -z "$TAPE" ] then echo a value is assigned to the TAPE variable else .... fi Method B if [ -n "$TAPE" ] then echo a value is assigned to the TAPE else .... fi The -n is optional and may be dropped. The shell parameter $TAPE is enclosed within double quotes to prevent test from issuing an error message in case no value has been assigned to the corresponding variable. |
See also
find |