15 August 2015

The first glance at the following examples may make you think the [ works as expected while the impelmentation of [[ has a bug. However, examining it more closely, you will find the later was designed to act that way and it is, in my opinion, a better design.

$ ls

$ # WRONG, but returns "expected result"
$ [ -f abc* ] && echo found || echo not found

$ # CORRECT, but returns "unexpected result"
$ [[ -f abc* ]] && echo found || echo not found
not found

As for [, it will expand "abc*" according to filename glob, which means the resulted expression can be [ -f ] or [ -f abc1 abc2 ... ]. Therefore, even though in this case it returns expected expression, it is incorrect. Moreover, this kind of errors are hard to reproduce elsewhere (although those who have clear understanding of shell expansion can sense the issue at a glimpse).

In contrast, [[ will NOT expand "abc*". Even though it might be "counter-intuitive" to many (as they would expect a filename glob expansion), it is a better design because it eliminates the aformentioned risk.

blog comments powered by Disqus