Deu a louca no ‘test’ do Bash
Mais uma característica mal documentada do Bash! Observe como funciona o comando [
(o mesmo que test
):
~ $ [ x -eq x ]; echo $?
bash: [: x: esperava expressão de número inteiro
2
Aqui, o erro é provocado pelo fato de x
não ser um número inteiro.
Mas, observe como o comando composto [[
lida com isso:
~ $ [[ x -eq x ]]; echo $?
0
Não há erro! Por quê?!
Nada a respeito em help test
nem em help [[
...
A resposta está no manual, mas é quase inútil para quem não entende como funcionam as expressões aritméticas:
When used with the [[ command, Arg1 and Arg2 are evaluated as arithmetic expressions (see ARITHMETIC EVALUATION above).
O que isso quer dizer?
Observe novamente:
~ $ [[ x -eq x ]]; echo $?
0
Aqui, x
é um nome válido para variáveis e, em expressões aritméticas, acontecem duas coisas:
- O acesso a valores em variáveis dispensam o
$
; - Variáveis indefinidas são avaliadas como zero (
0
)!
Logo, o comando composto [[
está avaliando:
~ $ [[ 0 -eq 0 ]]; echo $?
0
Observe como isso acontece atribuindo a x
um caractere inválido para nomes de variáveis:
~ $ x=.
~ $ [[ x -eq x ]]; echo $?
bash: [[: .: erro de sintaxe: esperava operando (token de erro é ".")
1
Mas, o mais impressionante é que, se o valor em x
for outro nome válido, nós teremos o mesmo problema com a avaliação como zero:
~ $ x=z
~ $ [[ x -eq x ]]; echo $?
0
Isso pode causar até um erro de recursividade:
~ $ x=x
~ $ [[ x -eq x ]]; echo $?
bash: [[: x: excedido o nível de recursividade da expressão (token de erro é "x")
1
Mais uma para os nossos livros das sombras!