Originalmente, [
foi implementado como um comando comum, idêntico a test
, exceto que ]
espera um argumento extra no final que deve ser ]
. (Ele ainda existe como um comando comum, mas a maioria dos shells também tem esses como built-ins.) Dado que é um comando comum sujeito a análise ordinária, ele não poderia usar operadores matemáticos <
e >
sem citar: [ ${SEC} > 1 ]
contém um operador de redirecionamento, é equivalente a [ ${SEC} ] >1
, redirecionando a saída (vazia) do comando [
para o arquivo chamado 1
. O comando [
segue principalmente a convenção usual de criar opções especiais começando com um traço: a maioria de seus operadores começa com um traço. Portanto, há [ -r foo ]
para testar se um arquivo é legível, [ -r foo -a -w bar ]
para combinar dois testes com o operador "e", [ $x -eq $y ]
para testar se $x
e $y
são iguais, etc.
Esses shells mais antigos tinham igualdade de string (o operador =
, um dos poucos que se desvia da convenção traço-letra), mas não a string ordering¹. Eles tiveram comparações numéricas, por exemplo, [ $x -le $y ]
para testar se o inteiro $x
é menor ou igual a $y
, e este conjunto de operadores inclui igualdade numérica [ $x -eq $y ]
onde [ 010 -eq 8 ]
porque um zero inicial significa que o número está em octal.
O Ksh introduziu a sintaxe [[ … ]]
, também disponível agora no bash e zsh. Ao contrário de [ … ]
, que é um comando comum, [[ … ]]
é reconhecido pelo analisador do shell e, portanto, caracteres especiais, como (
e <
, podem ser usados sem serem citados (e, na verdade, não devem ser citados). Como -lt
e amigos já estavam disponíveis para comparações numéricas, e =
já estava fazendo uma comparação de strings, <
e amigos eram operadores de comparação de strings (ordem lexicográfica¹). Assim, por exemplo, [ 9 -lt 10 ]
mas [[ 10 > 9 ]]
.
¹ A ordem das strings está disponível com o utilitário expr
; é um dos poucos usos de expr
que não foram incluídos por recursos de shells POSIX. Mas tenha em atenção que expr
utiliza o mesmo operador para comparações de cadeia e numéricas, portanto expr 9 \< 10
but expr a9 \> a10
.
² Se as strings são interpretadas como strings de bytes, ou como strings de caracteres na localidade atual, depende do shell