\section test test - perform tests on files and text

\subsection test-synopsis Synopsis
\fish{synopsis}
test [EXPRESSION]
[ [EXPRESSION] ]
\endfish

\subsection test-description 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.

\subsection test-files Operators for files and directories

- `-b FILE` returns true if `FILE` is a block device.

- `-c FILE` returns true if `FILE` is a character device.

- `-d FILE` returns true if `FILE` is a directory.

- `-e FILE` returns true if `FILE` exists.

- `-f FILE` returns true if `FILE` is a regular file.

- `-g FILE` returns true if `FILE` has the set-group-ID bit set.

- `-G FILE` returns true if `FILE` exists and has the same group ID as the current user.

- `-L FILE` returns true if `FILE` is a symbolic link.

- `-O FILE` returns true if `FILE` exists and is owned by the current user.

- `-p FILE` returns true if `FILE` is a named pipe.

- `-r FILE` returns true if `FILE` is marked as readable.

- `-s FILE` returns true if the size of `FILE` is greater than zero.

- `-S FILE` returns true if `FILE` is a socket.

- `-t FD` returns true if the file descriptor `FD` is a terminal (TTY).

- `-u FILE` returns true if `FILE` has the set-user-ID bit set.

- `-w FILE` returns true if `FILE` is marked as writable; note that this does not check if the filesystem is read-only.

- `-x FILE` returns true if `FILE` is marked as executable.

\subsection test-strings Operators for text strings

- `STRING1 = STRING2` returns true if the strings `STRING1` and `STRING2` are identical.

- `STRING1 != STRING2` returns true if the strings `STRING1` and `STRING2` are not identical.

- `-n STRING` returns true if the length of `STRING` is non-zero.

- `-z STRING` returns true if the length of `STRING` is zero.

\subsection test-numbers Operators to compare and examine numbers

- `NUM1 -eq NUM2` returns true if `NUM1` and `NUM2` are numerically equal.

- `NUM1 -ne NUM2` returns true if `NUM1` and `NUM2` are not numerically equal.

- `NUM1 -gt NUM2` returns true if `NUM1` is greater than `NUM2`.

- `NUM1 -ge NUM2` returns true if `NUM1` is greater than or equal to `NUM2`.

- `NUM1 -lt NUM2` returns true if `NUM1` is less than `NUM2`.

- `NUM1 -le NUM2` returns true if `NUM1` is less than or equal to `NUM2`.

Note that only integers are supported. For more complex mathematical operations, including fractions, the `env` program may be useful. Consult the documentation for your operating system.

\subsection test-combinators Operators to combine expressions

- `COND1 -a COND2` returns true if both `COND1` and `COND2` are true.

- `COND1 -o COND2` returns true if either `COND1` or `COND2` are true.

Expressions can be inverted using the `!` operator:

- `! EXPRESSION` returns true if `EXPRESSION` is false, and false if `EXPRESSION` is true.

Expressions can be grouped using parentheses.

- `( EXPRESSION )` returns the value of `EXPRESSION`.

 Note that parentheses will usually require escaping with `\(` to avoid being interpreted as a command substitution.


\subsection test-example Examples

If the `/tmp` directory exists, copy the `/etc/motd` file to it:

\fish
if test -d /tmp
    cp /etc/motd /tmp/motd
end
\endfish

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.)

\fish
if test -n "$MANPATH"
    echo $MANPATH
end
\endfish

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.

\fish
if test \( -f /foo -o -f /bar \) -a \( -f /baz -o -f /bat \)
    echo Success.
end.
\endfish

Numerical comparisons will simply fail if one of the operands is not a number:

\fish
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
\endfish

A common comparison is with $status:

\fish
if test $status -eq 0
    echo "Previous command succeeded"
end
\endfish

\subsection test-standards Standards

`test` implements a subset of the <a href="http://www.unix.com/man-page/POSIX/1/test/">IEEE Std 1003.1-2008 (POSIX.1) standard</a>. 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 `test` utility 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`.
