I get what I expected when doing this in
[ "a" == "a" ] && echo yes
It gave me
But when I do this in
zsh, I get the following:
zsh: = not found
Why does the same command (
/usr/bin/[) behave differently in different shells?
The difference is that zsh also has an
=foo expands to the path to the
foo executable. That means
== is treated as trying to find a command called
= in your
PATH. Since that command doesn't exist, you get the error
zsh: = not found
that you saw (and in fact, this same thing would happen even if you actually were using
You can use
== here if you really want. This works as you expected in zsh:
[ "a" "==" "a" ] && echo yes
because the quoting prevents
=word expansion running. You could also disable the
equals option with
However, you'd be better off either:
And zsh, and bash give the same answer (
type is builtin too for both shells):
$ type -a [ [ is a shell builtin [ is /usr/bin/[
[ is a shell builtin command in bash and in zsh:
$ type [ [ is a shell builtin
From the Shell Builtin Commands documentation:
Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of a simple command (see Simple Commands), the shell executes the command directly, without invoking another program. Builtin commands are necessary to implement functionality impossible or inconvenient to obtain with separate utilities.
The official documentation (
$ help test) only allows to use
STRING1 = STRING2
True if the strings are equal.
So, the correct expression would be:
$ [ "a" = "a" ] && echo yes yes
What happens is that bash is a bit less strict. Supporting the
== operator with
[ seems to be a bash extension and it is no recommended to use it:
string1 == string2
string1 = string2
True if the strings are equal. When used with the [[ command, this performs pattern matching as described above (see Conditional Constructs).
‘=’ should be used with the test command for POSIX conformance.
If you want to use
==, you should use the
$ [[ "a" == "a" ]] && echo yes yes
Keep in mind that
[[ is less portable (is not POSIX). But both bash and zsh support it.
In both shells,
[ utility is a shell builtin. This is the shells implementation of that tool, it is used in preference to the binary
/usr/bin/[. The different results you encounter is caused by different implementations.
[ utility accepts
CONDITIONAL EXPRESSIONS as the
[[ compound command. According to bashs man page both
== are valid:
string1 == string2 string1 = string2 True if the strings are equal. = should be used with the test command for POSIX conformance.
[ utility attempts to implement POSIX and its extensions where these are specified. In the specification of the POSIX test utility there is no
== operator defined.