2019-03-31 17:05:09 +08:00
.. _cmd-test:
2018-12-17 09:39:33 +08:00
test - perform tests on files and text
2019-01-03 12:10:47 +08:00
======================================
2018-12-17 09:39:33 +08:00
2018-12-18 09:58:24 +08:00
Synopsis
--------
2018-12-17 05:08:41 +08:00
2019-09-17 17:59:04 +08:00
::
test [EXPRESSION]
[ [EXPRESSION] ]
2018-12-18 09:58:24 +08:00
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Description
2019-01-03 12:10:47 +08:00
-----------
2018-12-17 05:08:41 +08:00
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.
2018-12-20 04:02:45 +08:00
The first form (`` test `` ) is preferred. For compatibility with other shells, the second form is available: a matching pair of square brackets (`` [ [EXPRESSION ] ] `` ).
2018-12-17 05:08:41 +08:00
This test is mostly POSIX-compatible.
2018-12-20 04:02:45 +08:00
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.
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Operators for files and directories
2019-01-03 12:10:47 +08:00
-----------------------------------
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -b FILE `` returns true if `` FILE `` is a block device.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -c FILE `` returns true if `` FILE `` is a character device.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -d FILE `` returns true if `` FILE `` is a directory.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -e FILE `` returns true if `` FILE `` exists.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -f FILE `` returns true if `` FILE `` is a regular file.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -g FILE `` returns true if `` FILE `` has the set-group-ID bit set.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -G FILE `` returns true if `` FILE `` exists and has the same group ID as the current user.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -k FILE `` returns true if `` FILE `` has the sticky bit set. If the OS does not support the concept it returns false. See https://en.wikipedia.org/wiki/Sticky_bit.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -L FILE `` returns true if `` FILE `` is a symbolic link.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -O FILE `` returns true if `` FILE `` exists and is owned by the current user.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -p FILE `` returns true if `` FILE `` is a named pipe.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -r FILE `` returns true if `` FILE `` is marked as readable.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -s FILE `` returns true if the size of `` FILE `` is greater than zero.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -S FILE `` returns true if `` FILE `` is a socket.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -t FD `` returns true if the file descriptor `` FD `` is a terminal (TTY).
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -u FILE `` returns true if `` FILE `` has the set-user-ID bit set.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -w FILE `` returns true if `` FILE `` is marked as writable; note that this does not check if the filesystem is read-only.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -x FILE `` returns true if `` FILE `` is marked as executable.
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Operators for text strings
2019-01-03 12:10:47 +08:00
--------------------------
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` STRING1 = STRING2 `` returns true if the strings `` STRING1 `` and `` STRING2 `` are identical.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` STRING1 != STRING2 `` returns true if the strings `` STRING1 `` and `` STRING2 `` are not identical.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -n STRING `` returns true if the length of `` STRING `` is non-zero.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` -z STRING `` returns true if the length of `` STRING `` is zero.
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Operators to compare and examine numbers
2019-01-03 12:10:47 +08:00
----------------------------------------
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -eq NUM2 `` returns true if `` NUM1 `` and `` NUM2 `` are numerically equal.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -ne NUM2 `` returns true if `` NUM1 `` and `` NUM2 `` are not numerically equal.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -gt NUM2 `` returns true if `` NUM1 `` is greater than `` NUM2 `` .
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -ge NUM2 `` returns true if `` NUM1 `` is greater than or equal to `` NUM2 `` .
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -lt NUM2 `` returns true if `` NUM1 `` is less than `` NUM2 `` .
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` NUM1 -le NUM2 `` returns true if `` NUM1 `` is less than or equal to `` NUM2 `` .
2018-12-17 05:08:41 +08:00
Both integers and floating point numbers are supported.
2018-12-19 10:44:30 +08:00
Operators to combine expressions
2019-01-03 12:10:47 +08:00
--------------------------------
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` COND1 -a COND2 `` returns true if both `` COND1 `` and `` COND2 `` are true.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` COND1 -o COND2 `` returns true if either `` COND1 `` or `` COND2 `` are true.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
Expressions can be inverted using the `` ! `` operator:
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- `` ! EXPRESSION `` returns true if `` EXPRESSION `` is false, and false if `` EXPRESSION `` is true.
2018-12-17 05:08:41 +08:00
Expressions can be grouped using parentheses.
2018-12-20 04:02:45 +08:00
- `` ( EXPRESSION ) `` returns the value of `` EXPRESSION `` .
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
Note that parentheses will usually require escaping with `` \( `` to avoid being interpreted as a command substitution.
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Examples
2019-01-03 12:10:47 +08:00
--------
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
If the `` /tmp `` directory exists, copy the `` /etc/motd `` file to it:
2018-12-17 05:08:41 +08:00
2018-12-19 11:14:04 +08:00
::
if test -d /tmp
cp /etc/motd /tmp/motd
end
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
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.)
2018-12-17 05:08:41 +08:00
2018-12-19 11:14:04 +08:00
::
if test -n "$MANPATH"
echo $MANPATH
end
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
Parentheses and the `` -o `` and `` -a `` operators can be combined to produce more complicated expressions. In this example, success is printed if there is a `` /foo `` or `` /bar `` file as well as a `` /baz `` or `` /bat `` file.
2018-12-17 05:08:41 +08:00
2018-12-19 11:14:04 +08:00
::
if test \( -f /foo -o -f /bar \) -a \( -f /baz -o -f /bat \)
echo Success.
end.
2018-12-17 05:08:41 +08:00
Numerical comparisons will simply fail if one of the operands is not a number:
2018-12-19 11:14:04 +08:00
::
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
2018-12-17 05:08:41 +08:00
A common comparison is with $status:
2018-12-19 11:14:04 +08:00
::
if test $status -eq 0
echo "Previous command succeeded"
end
2018-12-17 05:08:41 +08:00
The previous test can likewise be inverted:
2018-12-19 11:14:04 +08:00
::
if test ! $status -eq 0
echo "Previous command failed"
end
2018-12-17 05:08:41 +08:00
which is logically equivalent to the following:
2018-12-19 11:14:04 +08:00
::
if test $status -ne 0
echo "Previous command failed"
end
2018-12-17 05:08:41 +08:00
2018-12-19 10:44:30 +08:00
Standards
2019-01-03 12:10:47 +08:00
---------
2018-12-17 05:08:41 +08:00
2020-04-19 03:55:29 +08:00
`` test `` implements a subset of the `IEEE Std 1003.1-2008 (POSIX.1) standard <https://www.unix.com/man-page/posix/1p/test/> `__ . The following exceptions apply:
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- The `` < `` and `` > `` operators for comparing strings are not implemented.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
- 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 `` test `` utility in another shell.
2018-12-17 05:08:41 +08:00
2018-12-20 04:02:45 +08:00
In cases such as this, one can use `` command `` `` test `` to explicitly use the system's standalone `` test `` rather than this `` builtin `` `` test `` .