\section test test - perform tests on files and text

\subsection test-synopsis Synopsis
\fish{syn}
test [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 following operators are available to examine 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.

The following operators are available to compare and examine 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.

The following operators are available 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.

Expressions can be combined using the following operators:
- `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:

\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

\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`.

