test - evaluate expression
test [expression] [ [expression] ]
The test utility evaluates the expression and indicates the result of the evaluation by its exit status. An exit status of zero indicates that the expression evaluated as true and an exit status of 1 indicates that the expression evaluated as false.
In the second form of the utility, which uses  rather than test, the square brackets must be separate arguments.
The test utility does not recognise the -- argument in the manner specified by guideline 10 in the XBD specification, Utility Syntax Guidelines .
No options are supported.
All operators and elements of primaries must be presented as separate arguments to the test utility.
The following primaries can be used to construct expression:
- -b file
- True if file exists and is a block special file.
- -c file
- True if file exists and is a character special file.
- -d file
- True if file exists and is a directory.
- -e file
- True if file exists.
- -f file
- True if file exists and is a regular file.
- -g file
- True if file exists and its set group ID flag is set.
- -n string
- True if the length of string is non-zero.
- -p file
- True if file is a named pipe (FIFO).
- -r file
- True if file exists and is readable.
- -s file
- True if file exists and has a size greater than zero.
- -t file_descriptor
- True if the file whose file descriptor number is file_descriptor is open and is associated with a terminal.
- -u file
- True if file exists and its set-user-ID flag is set.
- -w file
- True if file exists and is writable. True will indicate only that the write flag is on. The file will not be writable on a read-only file system even if this test indicates true.
- -x file
- True if file exists and is executable. True will indicate only that the execute flag is on. If file is a directory, true indicates that file can be searched.
- -z string
- True if the length of string string is zero.
- True if the string string is not the null string.
- s1 = s2
- True if the strings s1 and s2 are identical.
- s1 != s2
- True if the strings s1 and s2 are not identical.
- n1 -eq n2
- True if the integers n1 and n2 are algebraically equal.
- n1 -ne n2
- True if the integers n1 and n2 are not algebraically equal.
- n1 -gt n2
- True if the integer n1 is algebraically greater than the integer n2.
- n1 -ge n2
- True if the integer n1 is algebraically greater than or equal to the integer n2.
- n1 -lt n2
- True if the integer n1 is algebraically less than the integer n2.
- n1 -le n2
- True if the integer n1 is algebraically less than or equal to the integer n2.
- expression1 -a expression2
- True if both expression1 and expression2 are true. The -a binary primary is left associative. It has a higher precedence than -o.
- expression1 -o expression2
- True if either expression1 or expression2 is true. The -o binary primary is left associative.
These primaries can be combined with the following operators:
- ! expression
- True if expression is false.
- ( expression )
- True if expression is true. The parentheses can be used to alter the normal precedence and associativity.
The primaries with two elements of the form:
are known as unary primaries. The primaries with three elements in either of the two forms:
primary_operand -primary_operator primary_operand
primary_operand primary_operator primary_operand
are known as binary primaries. Additional implementation-dependent operators and primary_operators may be provided by implementations. They will be of the form -operator where the first character of operator is not a digit.
The algorithm for determining the precedence of the operators and the return value that will be generated is based on the number of arguments presented to test. (However, when using the [...] form, the right-bracket final argument will not be counted in this algorithm.)
In the following list, $1, $2, $3 and $4 represent the arguments presented to test.
- 0 arguments:
- Exit false (1).
- 1 argument:
- Exit true (0) if $1 is not null; otherwise, exit false.
- 2 arguments:
- If $1 is "!", exit true if $2 is null, false if $2 is not null.
- If $1 is a unary primary, exit true if the unary test is true, false if the unary test is false.
- Otherwise, produce unspecified results.
- 3 arguments:
- If $2 is a binary primary, perform the binary test of $1 and $3.
- If $1 is "!", negate the two-argument test of $2 and $3.
- If $1 is "(" and $3 is ")", perform the unary test of $2.
- Otherwise, produce unspecified results.
- 4 arguments:
- If $1 is "!", negate the three-argument test of $2, $3 and $4.
- If $1 is "(" and $4 is ")", perform the two-argument test of $2 and $3.
- Otherwise, the results are unspecified.
- >4 arguments:
- Combinations of primaries and operators are evaluated using the precedence and associativity rules described previously. In addition, the string comparison binary primaries "=" and != have a higher precedence than any unary primary.
The following environment variables affect the execution of test:
- Provide a default value for the internationalisation variables that are unset or null. If LANG is unset or null, the corresponding value from the implementation-dependent default locale will be used. If any of the internationalisation variables contains an invalid setting, the utility will behave as if none of the variables had been defined.
- If set to a non-empty string value, override the values of all the other internationalisation variables.
- 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).
- Determine the locale that should be used to affect the format and contents of diagnostic messages written to standard error.
- Determine the location of message catalogues for the processing of LC_MESSAGES .
Used only for diagnostic messages.
The following exit values are returned:
- expression evaluated to true.
- expression evaluated to false or expression was missing.
- An error occurred.
Scripts should be careful when dealing with user-supplied input that could be confused with primaries and operators. Unless the application writer knows all the cases that produce input to the script, invocations like:should be written as:
test "$1" -a "$2"to avoid problems if a user supplied values such as $1 set to "!" and $2 set to the null string. That is, in cases where maximal portability is of concern, replace:
test "$1" && test "$2"with:
test expr1 -a expr2and replace:
test expr1 && test expr2with:
test expr1 -o expr2but note that, in test, -a has higher precedence than -o while && and || have equal precedence in the shell.
test expr1 || test expr2
Parentheses or braces can be used in the shell command language to effect grouping.
Parentheses must be escaped when using sh; for example:
test \( expr1 -a expr2 \) -o expr3
This command is not always portable outside XSI-conformant systems. The following form can be used instead:
( test expr1 && test expr2 ) || test expr3
The two commands:could not be used reliably on some historical systems. Unexpected results would occur if such a string expression were used and $1 expanded to "!", "(" or a known unary primary. Better constructs are:
test "$1" test ! "$1"respectively.
test -n "$1" test -z "$1"
Historical systems have also been unreliable given the common construct:One of the following is a more reliable form:
test "$response" = "expected string"
test "X$response" = "Xexpected string" test "expected string" = "$response"
Note that the second form assumes that expected string could not be confused with any unary primary. If expected string starts with "-", "(", "!" or even "=", the first form should be used instead. Using the preceding rules without the marked extensions, any of the three comparison forms is reliable, given any input. (However, note that the strings are quoted in all cases.)
Because the string comparison binary primaries, "=" and !=, have a higher precedence than any unary primary in the greater than 4 argument case, unexpected results can occur if arguments are not properly prepared. For example, in:
test -d $1 -o -d $2
If $1 evaluates to a possible directory name of =, the first three arguments are considered a string comparison, which causes a syntax error when the second -d is encountered. One of the following forms prevents this; the second is preferred:
test \( -d "$1" \) -o \( -d "$2" \) test -d "$1" || test -d "$2"
Also in the greater than 4 argument case:Syntax errors will occur if $1 evaluates to "(" or "!". One of the following forms prevents this; the third is preferred:
test "$1" = "bat" -a "$2" = "ball"
test "X$1" = "Xbat" -a "X$2" = "Xball" test "$1" = "bat" && test "$2" = "ball" test "X$1" = "Xbat" && test "X$2" = "Xball"
- Exit if there are not two or three arguments (two variations):
if [ $# -ne 2 -a $# -ne 3 ]; then exit 1; fi if [ $# -lt 2 -o $# -gt 3 ]; then exit 1; fi
- Perform a mkdir if a directory does not exist:
test ! -d tempdir && mkdir tempdir
- Wait for a file to become non-readable:
while test -r thefile do sleep 30 done echo '"thefile" is no longer readable'
- Perform a command if the argument is one of three strings (two variations):
if [ "$1" = "pear" ] || [ "$1" = "grape" ] || [ "$1" = "apple" ] then command fi case "$1" in pear|grape|apple) command ;; esac
The IEEE PASC 1003.2 Interpretations Committee has forwarded concerns about parts of this interface definition to the IEEE PASC Shell and Utilities Working Group which is identifying the corrections. A future revision of this specification will align with IEEE Std. 1003.2b when finalised.