pim@cti-software.nl (Pim Zandbergen) (08/09/90)
Need I be more specific? -- Pim Zandbergen domain : pim@cti-software.nl CTI Software BV uucp : uunet!mcsun!hp4nl!ctisbv!pim Laan Copes van Cattenburch 70 phone : +31 70 3542302 2585 GD The Hague, The Netherlands fax : +31 70 3512837
ekrell@ulysses.att.com (Eduardo Krell) (08/10/90)
Answer from Dave Korn: The primary difference between [ and [[ is that [ is a command (equivalent to the test command), whereas [[ is part of the shell grammar. There are a few minor differences as well. In particular, [ uses -a and -o for and and or, whereas [[ uses && and || for this. Because [ is a command, all shell expansions are performed before the [ command is executed. The only way to distinguish between operators and operands is by the results of expansions. For example, [ "$1" ] can have several meanings that depend of the value of $1. If $1 is -t, then this is a test for a terminal. If $1 is of the form, -<letter>, where letter is one of the unary operators that require an operand, then this is an error. Otherwise, this evaluates to true when the string is not null. Note that the use of double quotes is critical with [ since otherwise it need not expand to a single argument which leads to unexpected results. There are many other anomalies with [. Here are a few: 1. To test string variables you have to precede the variable with a character that is not a - to prevent it being interpreted as an operator. 2. [ -f * ] tests the first file name and ignores the rest, unless the second name is -a, -o, or a binary operator such as =. 3. [ -f "$1" ] yields a syntax error when $1 is =. The [[...]] construct was added to ksh88 to overcome these problems. Since [[...]] is part of the shell, it can differenciate between operators and operands before expansion. (This means that the operators cannot be variable unless you use eval). In addition, word splitting and file name expansion are not performed inside [[...]] eliminating many of the most common scripting errors. Because no file expansion is done, pattern characters (*,? and [) can be used for string comparison. The [[...]] construct was in draft 8 of the IEEE 1003.2 shell and utilities standard, but was removed from draft 9 because it was felt that some of these problems could be fixed by eliminating compound operations, -a, -o, !, and () in test ([) from the standard and requiring that -t require an operand. The number of arguments could then determine which argument was an operator. Writing a compound command would requiring the use the && and || of the shell instead. The ! command was added to the shell grammar for this purpose. Unfortunately, there was no coordination between changes in test and the shell language so that the changes in test were never made and the [[...]] was not restored. Therefore, unless there is a change in future version of the standard, the [[...]] will remain a KornShell extension rather than part of the POSIX shell language. David Korn ulysses!dgk Eduardo Krell AT&T Bell Laboratories, Murray Hill, NJ UUCP: {att,decvax,ucbvax}!ulysses!ekrell Internet: ekrell@ulysses.att.com