The KornShell-derived conditional command (double bracket [[]]
)
was removed from the shell command language description in an
early proposal. Objections were raised that the real problem is
misuse of the test command ([
), and putting it into the shell is
the wrong way to fix the problem. Instead, proper documentation
and a new shell reserved word (!
) are sufficient.
Tests that require multiple test operations can be done at the
shell level using individual invocations of the test command and
shell logicals, rather than using the error-prone -o
flag of
test.
XSI-conformant systems support more than four arguments.
XSI-conformant systems support the combining of primaries with
the following constructs:
expression1 -a
expression2
True if both expression1 and expression2 are true.
expression1 -o
expression2
True if at least one of expression1 and expression2 are
true.
(
expression )
True if expression is true.
In evaluating these more complex combined expressions, the
following precedence rules are used:
* The unary primaries have higher precedence than the algebraic
binary primaries.
* The unary primaries have lower precedence than the string
binary primaries.
* The unary and binary primaries have higher precedence than
the unary string primary.
* The !
operator has higher precedence than the -a
operator,
and the -a
operator has higher precedence than the -o
operator.
* The -a
and -o
operators are left associative.
* The parentheses can be used to alter the normal precedence
and associativity.
The BSD and System V versions of -f
are not the same. The BSD
definition was:
-f
file True if file exists and is not a directory.
The SVID version (true if the file exists and is a regular file)
was chosen for this volume of POSIX.1‐2017 because its use is
consistent with the -b
, -c
, -d
, and -p
operands (file exists and
is a specific file type).
The -e
primary, possessing similar functionality to that provided
by the C shell, was added because it provides the only way for a
shell script to find out if a file exists without trying to open
the file. Since implementations are allowed to add additional
file types, a portable script cannot use:
test -b foo -o -c foo -o -d foo -o -f foo -o -p foo
to find out if foo
is an existing file. On historical BSD
systems, the existence of a file could be determined by:
test -f foo -o -d foo
but there was no easy way to determine that an existing file was
a regular file. An early proposal used the KornShell -a
primary
(with the same meaning), but this was changed to -e
because there
were concerns about the high probability of humans confusing the
-a
primary with the -a
binary operator.
The following options were not included in this volume of
POSIX.1‐2017, although they are provided by some implementations.
These operands should not be used by new implementations for
other purposes:
-k
file True if file exists and its sticky bit is set.
-C
file True if file is a contiguous file.
-V
file True if file is a version file.
The following option was not included because it was undocumented
in most implementations, has been removed from some
implementations (including System V), and the functionality is
provided by the shell (see Section 2.6.2, Parameter Expansion.
-l
string The length of the string string.
The -b
, -c
, -g
, -p
, -u
, and -x
operands are derived from the
SVID; historical BSD does not provide them. The -k
operand is
derived from System V; historical BSD does not provide it.
On historical BSD systems, test -w
directory always returned
false because test tried to open the directory for writing, which
always fails.
Some additional primaries newly invented or from the KornShell
appeared in an early proposal as part of the conditional command
([[]]
): s1 >
s2, s1 <
s2, str =
pattern, str !=
pattern, f1 -nt
f2, f1 -ot
f2, and f1 -ef
f2. They were not carried forward into
the test utility when the conditional command was removed from
the shell because they have not been included in the test utility
built into historical implementations of the sh utility.
The -t
file_descriptor primary is shown with a mandatory argument
because the grammar is ambiguous if it can be omitted. Historical
implementations have allowed it to be omitted, providing a
default of 1.
It is noted that '['
is not part of the portable filename
character set; however, since it is required to be encoded by a
single byte, and is part of the portable character set, the name
of this utility forms a character string across all supported
locales.