Comparar número inteiro no bash, operador unário esperado

137

O código a seguir fornece

[: -ge: operador unário esperado

quando

i=0

if [ $i -ge 2 ]
then
    #some code
fi

porque?

Filip Ekberg
fonte

Respostas:

295

Seu problema surge do fato de $iter um valor em branco quando sua instrução falhar. Sempre cite suas variáveis ​​ao realizar comparações, se houver a menor chance de uma delas estar vazia, por exemplo:

if [ "$i" -ge 2 ] ; then
  ...
fi

Isso ocorre devido à maneira como o shell trata as variáveis. Suponha o exemplo original,

if [ $i -ge 2 ] ; then ...

A primeira coisa que o shell faz ao executar essa linha de código específica é substituir o valor de $i, exatamente como faria a função de pesquisa e substituição do seu editor favorito . Então, suponha que $iesteja vazio ou, ainda mais ilustrativo, assuma que $ihá muitos espaços! O shell será substituído da $iseguinte maneira:

if [     -ge 2 ] ; then ...

Agora que as substituições de variáveis ​​são feitas, o shell prossegue com a comparação e ... falha porque não pode ver nada inteligível à esquerda de -gt. No entanto, citando $i:

if [ "$i" -ge 2 ] ; then ...

torna-se:

if [ "    " -ge 2 ] ; then ...

O shell agora vê aspas duplas e sabe que você está realmente comparando quatro espaços em branco a 2 e ignorará o if.

Você também tem a opção de especificar um valor padrão para $iif $iestá em branco, da seguinte maneira:

if [ "${i:-0}" -ge 2 ] ; then ...

Isto irá substituir o valor 0 em vez de $ise $ié indefinido. Ainda mantenho as aspas porque, novamente, se $ihouver um monte de espaços em branco, ele não será considerado indefinido , não será substituído por 0 e você enfrentará o problema novamente.

Por favor, leia isso quando tiver tempo. O shell é tratado como uma caixa preta por muitos, mas opera com muito poucas e muito simples regras - assim que você souber quais são essas regras (uma delas é como as variáveis ​​funcionam no shell, conforme explicado acima), o shell será Não tenho mais segredos para você.

vladr
fonte
7
variável de citação aumentará um novo erro como a expressão inteira esperada
Néstor
@ Néstor errado , citar uma variável NÃO gerará um novo erro como a expressão inteira esperada se a variável for numérica; fornecendo um valor variável não numérico, seja citado ou não, irá resultar no referido erro.
vladr
6

A julgar pela mensagem de erro, o valor de i era a cadeia vazia quando você a executou, não 0.

starblue
fonte
6

Eu preciso adicionar meus 5 centavos. Eu vejo todo mundo usar [ou [[, mas vale a pena mencionar que eles não fazem parte da sintaxe.

Para comparações aritméticas, use em seu ((...))lugar.

((...)) é um comando aritmético, que retorna um status de saída 0 se a expressão for diferente de zero ou 1 se a expressão for zero. Também usado como sinônimo de "let", se forem necessários efeitos colaterais (atribuições).

Consulte: Expressão Aritmética

Roman Newaza
fonte
2

Seu pedaço de script funciona muito bem. Tem certeza de que não está atribuindo mais nada antes do if para "i"?

Um erro comum também é não deixar um espaço antes e antes dos colchetes.

Fernando Miguélez
fonte