test - perform tests on files and text¶
test [EXPRESSION] [ [EXPRESSION] ]
Tests the expression given and sets the exit status to 0 if true, and 1 if false. An expression is made up of one or more operators and their arguments.
The first form (
test) is preferred. For compatibility with other shells, the second form is available: a matching pair of square brackets (
[ [EXPRESSION ] ]).
This test is mostly POSIX-compatible.
When using a variable as an argument for a test operator you should almost always enclose it in double-quotes. There are only two situations it is safe to omit the quote marks. The first is when the argument is a literal string with no whitespace or other characters special to the shell (e.g., semicolon). For example,
test -b /my/file. The second is using a variable that expands to exactly one element including if that element is the empty string (e.g.,
set x ''). If the variable is not set, set but with no value, or set to more than one value you must enclose it in double-quotes. For example,
test "$x" = "$y". Since it is always safe to enclose variables in double-quotes when used as
test arguments that is the recommended practice.
Operators for files and directories¶
-b FILEreturns true if
FILEis a block device.
-c FILEreturns true if
FILEis a character device.
-d FILEreturns true if
FILEis a directory.
-e FILEreturns true if
-f FILEreturns true if
FILEis a regular file.
-g FILEreturns true if
FILEhas the set-group-ID bit set.
-G FILEreturns true if
FILEexists and has the same group ID as the current user.
-k FILEreturns true if
FILEhas the sticky bit set. If the OS does not support the concept it returns false. See https://en.wikipedia.org/wiki/Sticky_bit.
-L FILEreturns true if
FILEis a symbolic link.
-O FILEreturns true if
FILEexists and is owned by the current user.
-p FILEreturns true if
FILEis a named pipe.
-r FILEreturns true if
FILEis marked as readable.
-s FILEreturns true if the size of
FILEis greater than zero.
-S FILEreturns true if
FILEis a socket.
-t FDreturns true if the file descriptor
FDis a terminal (TTY).
-u FILEreturns true if
FILEhas the set-user-ID bit set.
-w FILEreturns true if
FILEis marked as writable; note that this does not check if the filesystem is read-only.
-x FILEreturns true if
FILEis marked as executable.
Operators for text strings¶
STRING1 = STRING2returns true if the strings
STRING1 != STRING2returns true if the strings
STRING2are not identical.
-n STRINGreturns true if the length of
-z STRINGreturns true if the length of
Operators to compare and examine numbers¶
NUM1 -eq NUM2returns true if
NUM2are numerically equal.
NUM1 -ne NUM2returns true if
NUM2are not numerically equal.
NUM1 -gt NUM2returns true if
NUM1is greater than
NUM1 -ge NUM2returns true if
NUM1is greater than or equal to
NUM1 -lt NUM2returns true if
NUM1is less than
NUM1 -le NUM2returns true if
NUM1is less than or equal to
Both integers and floating point numbers are supported.
Operators to combine expressions¶
COND1 -a COND2returns true if both
COND1 -o COND2returns true if either
Expressions can be inverted using the
! EXPRESSIONreturns true if
EXPRESSIONis false, and false if
Expressions can be grouped using parentheses.
( EXPRESSION )returns the value of
Note that parentheses will usually require escaping with
\(to avoid being interpreted as a command substitution.
/tmp directory exists, copy the
/etc/motd file to it:
if test -d /tmp cp /etc/motd /tmp/motd end
If the variable
MANPATH is defined and not empty, print the contents. (If
MANPATH is not defined, then it will expand to zero arguments, unless quoted.)
if test -n "$MANPATH" echo $MANPATH end
Parentheses and the
-a operators can be combined to produce more complicated expressions. In this example, success is printed if there is a
/bar file as well as a
if test \( -f /foo -o -f /bar \) -a \( -f /baz -o -f /bat \) echo Success. end.
Numerical comparisons will simply fail if one of the operands is not a number:
if test 42 -eq "The answer to life, the universe and everything" echo So long and thanks for all the fish # will not be executed end
A common comparison is with $status:
if test $status -eq 0 echo "Previous command succeeded" end
The previous test can likewise be inverted:
if test ! $status -eq 0 echo "Previous command failed" end
which is logically equivalent to the following:
if test $status -ne 0 echo "Previous command failed" end
test implements a subset of the IEEE Std 1003.1-2008 (POSIX.1) standard. The following exceptions apply:
>operators for comparing strings are not implemented.
Because this test is a shell builtin and not a standalone utility, using the -c flag on a special file descriptors like standard input and output may not return the same result when invoked from within a pipe as one would expect when invoking the
testutility in another shell.
In cases such as this, one can use
testto explicitly use the system's standalone
testrather than this