test - perform tests on files and text
Synopsis
test [EXPRESSION] [ [EXPRESSION] ]
Description
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 ifFILEis a block device. -
-c FILEreturns true ifFILEis a character device. -
-d FILEreturns true ifFILEis a directory. -
-e FILEreturns true ifFILEexists. -
-f FILEreturns true ifFILEis a regular file. -
-g FILEreturns true ifFILEhas the set-group-ID bit set. -
-G FILEreturns true ifFILEexists and has the same group ID as the current user. -
-k FILEreturns true ifFILEhas 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 ifFILEis a symbolic link. -
-O FILEreturns true ifFILEexists and is owned by the current user. -
-p FILEreturns true ifFILEis a named pipe. -
-r FILEreturns true ifFILEis marked as readable. -
-s FILEreturns true if the size ofFILEis greater than zero. -
-S FILEreturns true ifFILEis a socket. -
-t FDreturns true if the file descriptorFDis a terminal (TTY). -
-u FILEreturns true ifFILEhas the set-user-ID bit set. -
-w FILEreturns true ifFILEis marked as writable; note that this does not check if the filesystem is read-only. -
-x FILEreturns true ifFILEis marked as executable.
Operators for text strings
-
STRING1 = STRING2returns true if the stringsSTRING1andSTRING2are identical. -
STRING1 != STRING2returns true if the stringsSTRING1andSTRING2are not identical. -
-n STRINGreturns true if the length ofSTRINGis non-zero. -
-z STRINGreturns true if the length ofSTRINGis zero.
Operators to compare and examine numbers
-
NUM1 -eq NUM2returns true ifNUM1andNUM2are numerically equal. -
NUM1 -ne NUM2returns true ifNUM1andNUM2are not numerically equal. -
NUM1 -gt NUM2returns true ifNUM1is greater thanNUM2. -
NUM1 -ge NUM2returns true ifNUM1is greater than or equal toNUM2. -
NUM1 -lt NUM2returns true ifNUM1is less thanNUM2. -
NUM1 -le NUM2returns true ifNUM1is less than or equal toNUM2.
Both integers and floating point numbers are supported.
Operators to combine expressions
-
COND1 -a COND2returns true if bothCOND1andCOND2are true. -
COND1 -o COND2returns true if eitherCOND1orCOND2are true.
Expressions can be inverted using the ! operator:
-
! EXPRESSIONreturns true ifEXPRESSIONis false, and false ifEXPRESSIONis true.
Expressions can be grouped using parentheses.
-
( EXPRESSION )returns the value ofEXPRESSION.
Note that parentheses will usually require escaping with \( to avoid being interpreted as a command substitution.
Examples
If the /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 -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.
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
Standards
test implements a subset of the IEEE Std 1003.1-2008 (POSIX.1) standard. The following exceptions apply:
- The
<and>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 command test to explicitly use the system's standalone test rather than this builtin test.
© 2021 fish-shell developers
Licensed under the GNU General Public License, version 2.
https://fishshell.com/docs/3.3/cmds/test.html