Por curiosidade, ao fazer uma comparação de variáveis bash (seu valor é um integer
), é possível testá-lo em relação a algum valor predefinido, declarado como int
ou como string
.
Exemplo de script :
#!/bin/bash
f1()
{
[ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}
f2()
{
[[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}
f1 $1
f2 $1
Saída :
$ ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int
e
$ ./param.sh blah
$
Ambas as funções se comportam da mesma maneira, e então eu estou querendo saber se há uma maneira preferida ao verificar uma variável inteira? Eu iria para a verificação int
versus int
, pois é mais rigoroso, mas gostaria de saber se há alguma desvantagem em fazê-lo string
?
Nesse caso, f2()
também é mais rigoroso quanto à comparação, ou seja, passar um valor decimal o quebrará, enquanto f1()
isso não causará problemas.
Respostas:
Sim, muitas diferenças. Por exemplo,
=
verifica a igualdade exata da string, mas-eq
avalia as duas expressões aritmeticamente antes de verificar a igualdade:Além disso, a cadeia vazia é numericamente igual a zero:
E toda uma outra classe de diferenças aparece quando você coloca os operadores de comparação - considerando
<
vs-lt
, por exemplo:Isso ocorre porque a sequência "2" é alfabética após a sequência "10" (já que 1 vem antes de 2), mas o número "2" é numericamente menor que o número "10".
fonte
(( ... ))
há operações numéricas.(( " 1 " == 1 )) && echo yes || echo no
resultados emyes
A comparação entre números inteiros e seqüências de caracteres se torna mais significativa quando você está comparando maior ou menor que:
O primeiro falha porque 9 vem após 11 quando classificado lexicograficamente.
Observe que o uso de aspas não determina se você está comparando cadeias ou números, o operador faz. Você pode adicionar ou remover as aspas acima, isso não faz nenhuma diferença. O Bash captura variáveis indefinidas entre colchetes duplos, portanto, as aspas não são necessárias. Usar aspas com colchetes simples para testes numéricos não o salvará, pois:
de qualquer maneira, é um erro ("é necessária uma expressão inteira"). As cotações são uma salvaguarda eficaz com comparações de cadeias entre colchetes:
Observe entre parênteses duplos , mas
""
será que-eq 0
não== 0
.fonte
[[
é inteligente o suficiente para lembrar onde estão as variáveis e não será enganado por variáveis vazias. Parênteses simples ([
) não possuem esse recurso e requerem aspas.[[ -lt 11 ]]
é um erro, masnothing=; [[ $nothing -lt 11 ]]
não é. Eu refiz um pouco o último parágrafo.Além do que foi dito.
A comparação da igualdade é mais rápida com os números, embora nos scripts de shell seja raro que você precise de um cálculo rápido.
fonte
=
, pois o uso-eq
corresponderia a "+123" também. Se você quiser saber "Essa variável, quando avaliada como uma expressão aritmética, compara com igual a 123", você só pode usar-eq
. A única vez em que vejo onde um programador não se importaria com qual definição de igualdade foi usada é quando ele sabe que o conteúdo da variável é restrito a um padrão específico antes do tempo.b=234
) se encaixa nesse padrão - você sabe que não é +234 ou "234" ou "233 + 1", desde que você o designou, então você sabe que compará-lo como uma sequência e como um número são igualmente válidos. Mas o roteiro do OP, uma vez que leva de entrada como um argumento de linha de comando, não tem essa restrição - considerar chamar-lo como./param.sh 0+1
ou./param.sh " 1"