Para quem não sabe, no
bash, não é obrigatório o uso do programa
test para comparação de variáveis. Digo isso pois todo mundo aprende, nos mais diversos tutoriais que encontramos na internet, a fazer comparações com o uso deste programa. Qual o problema disso?
- Uma sintaxe diferente da que encontramos em outras linguagens.
- Como o test é um programa externo e não um built-in do bash, sua execução é mais lenta.
O que eu pretendo com esta dica?
- Mostrar uma sintaxe mais limpa para tais operações, a fim de tornar o código muito parecido com o mesmo código em linguagens como c/c++.
- Tornar a execução do programa mais rápida (se bem que, como estamos falando de shell-script, isso não faz muita diferença).
Primeiramente, vou começar com o seguinte código, escrito em "shell normal":
$ i=$RANDOM
$ j=$RANDOM
$ if [ $i -eq 20 -o $j -eq 30 ]
> then
> echo I é igual a vinte ou J é igual a 30
> fi
A mesma comparação no if poderia ser escrita com dois test's:
$ if [ $i -eq 20 ] || [ $j -eq 30 ]
> (...)
Mas, como estamos utilizando dois test's, há perda de desempenho.
Agora, o mesmo código em bash puro:
$ i=$RANDOM
$ j=$RANDOM
$ if (( ( i == 20 ) || ( i == 20 ) ))
> then
> echo I é igual a vinte ou J é igual a 30
> fi
Ou a condição poderia ser dividida em duas operações:
$ if (( i == 20 )) || (( i == 20 ))
> (...)
Novamente, o problema da execução de mais de uma operação.
Algumas outras equivalências entre o test e o bash:
$a -lt $b <=> (( a < b ))
$a -le $b <=> (( a <= b ))
$a -gt $b <=> (( a > b ))
$a -ge $b <=> (( a >= b ))
$a -eq $b <=>(( a == b ))
$a -ne $b <=> (( a != b ))
Além desse tipo de comparação, podemos realizar tarefas como:
$ incremento=2
$ i=1
$ (( i+=incremento )) ## isso acrescenta 2 à variável i, que fica com o valor 3
O mesmo vale para operações como subtração (/), multiplicação (*) e módulo (%). Ou se você quiser, simplesmente, adicionar 1 à variável, use:
$ ((i++)) # pós-incremento
$ ((++i)) # pré-incremento
$ ((i--)) # pós-decremento
$ ((--i)) # pré-decremento
Também é possível utilizar uma atribuição "normal":
$ (( i = (j%20)+1 ))
$ ((i=i**3)) # Eleva i ao cubo
Com tudo isso e mais alguns conhecimentos de tratamento de variáveis no bash, podemos substituir os comandos -z e -n do test!
$ if (( ${#i} == 0 ))
> then
> echo a variável i não está definida
> fi
Este comando equivale ao -z (string nula). Quanto ao -n, basta substituir o '==' por um '!='.