Why is the bash builtin `test' slightly different from /bin/test?
 Why is the bash builtin `test' slightly different from /bin/test?
The specific example used here is [ ! x -o x ], which is false.
Bash's builtin `test' implements the Posix.2 spec, which can be
summarized as follows (the wording is due to David Korn):
   
Here is the set of rules for processing test arguments.
  
    0 Args: False
    1 Arg:  True iff argument is not null.
    2 Args: If first arg is !, True iff second argument is null.
	    If first argument is unary, then true if unary test is true
	    Otherwise error.
    3 Args: If second argument is a binary operator, do binary test of $1 $3
	    If first argument is !, negate two argument test of $2 $3
	    If first argument is `(' and third argument is `)', do the
	    one-argument test of the second argument.
	    Otherwise error.
    4 Args: If first argument is !, negate three argument test of $2 $3 $4.
	    Otherwise unspecified
    5 or more Args: unspecified.  (Historical shells would use their
    current algorithm).
   
The operators -a and -o are considered binary operators for the purpose
of the 3 Arg case.
   
As you can see, the test becomes (not (x or x)), which is false.