Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I just wondered what exactly the difference between

[[ $STRING != foo ]]

and

[ $STRING != foo ]

is, apart from that the latter is posix-compliant, found in sh and the former is an extension found in bash.

share|improve this question

3 Answers 3

up vote 73 down vote accepted

There are several differences. In my opinion, a few of the most important are:

  1. [ is a builtin in Bash and many other modern shells. The builtin [ is similar to test with the additional requirement of a closing ]. The builtins [ and test imitate the functionality /bin/[ and /bin/test along with their limitations so that scripts would be backwards compatible. The original executables still exist mostly for POSIX compliance and backwards compatibility. Running the command type [ in Bash indicates that [ is interpreted as a builtin by default. (Note: which [ only looks for executables on the PATH and is equivalent to type -P [)
  2. [[ is not as compatible, it generally won't work with whatever /bin/sh points to. So [[ is the more modern bash / zsh / korn option.
  3. Because [[ is built in to the shell and does not have legacy requirements, you don't need to worry about word splitting based on the IFS variable to mess up on variables that evaluate to a string with spaces. Therefore, you don't really need to put the variable in double quotes.

For the most part, the rest is just some nicer syntax. To see more differences, I recommend this link to a FAQ answer: What is the difference between test, [ and [[ ?. In fact, if you are serious about bash scripting, I recommend reading the entire wiki, including the FAQ, Pitfalls, and Guide. The test section from the guide section explains these differences as well, and why the author(s) think [[ is a better choice if you don't need to worry about being as portable. The main reasons are:

  1. You don't have to worry about quoting the left hand side of the test so that it actually gets read as a variable.
  2. You don't have to escape less than and greater than < > with backslashes in order for them not to get evaluated as input redirection, which can really mess some stuff up by over writing files. This again goes back to [[ being a builtin. If [ (test) is an external program the shell would have to make an exception in the way it evaluates < and > only if /bin/test is being called, which wouldn't really make sense.
share|improve this answer
2  
Thanks, the link to the bash FAQ was what I was looking for (did not know about that page, thanks). –  0x89 Aug 9 '09 at 22:07
    
I edited your post with this information, but [ and test are executed as builtins. The builtins were designed to replace /bin/[ and /bin/test but needed to reproduce the limitations of the binaries too. The command 'type [' verifies that the builtin is used. 'which [' only searches for executables on the PATH and is equivalent to 'type -P [' –  klynch Jul 18 '11 at 22:55

In Short:

[ ] are bash Builtins

[[ ]] are bash Keywords

Keywords: Keywords are quite like builtins, but the main difference is that special parsing rules apply to them. For example, [ is a bash builtin, while [[ is a bash keyword. They are both used for testing stuff, but since [[ is a keyword rather than a builtin, it benefits from a few special parsing rules which make it a lot easier:

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

The first example returns an error because bash tries to redirect the file b to the command [ a ]. The second example actually does what you expect it to. The character < no longer has its special meaning of File Redirection operator.

Source: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments

share|improve this answer

Based on a quick reading of the relevant sections of the manpage, the primary difference appears to be that the == and != operators match against a pattern, rather than a literal string, and also that there's the =~ regex comparison operator.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.