2 of 3 Fixed the info about the `[ expr ]`

From the bash documentation:

(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.

In other words, you make sure that whatever happens in 'list' (like a cd) has no effect outside of the ( and ).

((expression)) The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "expression".

This is a bash extension allowing you to do math. This is somewhat similar to using expr without all the limitations of expr (such as having spaces everywhere, escaping *, etc.)

[[ expression ]] Return a status of 0 or 1 depending on the evaluation of the conditional expression expression. Expressions are composed of the primaries described below under CONDITIONAL EXPRESSIONS. Word splitting and pathname expansion are not performed on the words between the [[ and ]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. Conditional operators such as -f must be unquoted to be recognized as primaries.

When used with [[, the < and > operators sort lexicographically using the current locale.

This offers an advanced test to compare strings, numbers, and files a bit like test offers, but more powerful.

[ expr ] Return a status of 0 (true) or 1 (false) depending on the evaluation of the conditional expression expr. Each operator and oper and must be a separate argument. Expressions are composed of the primaries described above under CONDITIONAL EXPRESSIONS. test does not accept any options, nor does it accept and ignore an argument of -- as signifying the end of options.


This one calls test. Actually, in the old days, [ was a symbolic link to test. It works the same way and you have the same limitations. Since a binary knows the name with which it was started, the test program can parse parameters until it finds a parameter ]. Fun Unix tricks.

Note that in case of bash, [ and test are built-in functions (as mentioned in a comment), yet pretty much the same limitations apply.