Se a instrução funcionar com [mas não com [[ao comparar strings com -eq [duplicate]

0
    

Esta pergunta já tem uma resposta aqui:

    

Meu código:

#!/bin/bash

x=${#}

for (( a=0; a<x; ++a)); do
   if [[ $1 -eq $1 ]] 2> /dev/null
   then
      variable[a]=${1}
      shift
   else
      echo "The argument $1 is NOT an integer. Aborting this"
      exit 1
   fi
done
TOTAL=0
for (( a=0; a<x; ++a)); do
      echo "TOTAL : ${TOTAL}"
      TOTAL=$((TOTAL+variable[a]))
done
echo "Everything accounted to $TOTAL"
exit 0

Então, basicamente, ele pega os argumentos do script e os resume. Se um dos argumentos não for um número inteiro, ele deverá informar e sair do script.

Do jeito que está agora, não me diz se um dos argumentos não é um inteiro, apenas o ignora. Então, dando-lhe os argumentos 123 123 123 asdt, eu recebo o seguinte:

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
TOTAL : 0
TOTAL : 123
TOTAL : 246
TOTAL : 369
Everything accounted to 369
[07:43----------------------------------------
vagrant@localhost vagrant]$

Mas se eu mudar isso:

for (( a=0; a<x; ++a)); do
   if [ $1 -eq $1 ] 2> /dev/null
   then

Funciona e eu entendo isso:

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
The argument asdt is NOT an integer. Aborting this
[07:44----------------------------------------
vagrant@localhost vagrant]$

Por que isso acontece?

    
por iamAguest 22.08.2018 / 13:45

1 resposta

3

É uma das coisas como [[ .. ]] é especial no Bash. [[ a -eq b ]] forces a e b a serem tomadas como expressões aritméticas, e dentro de uma, uma string é tomada como o nome de uma variável. Outras expressões também funcionam, então você pode fazer isso:

$ a=2
$ [[ a -eq 1+1 ]] && echo yes
yes

Por outro lado, [ é um comando comum e obedece à mesma sintaxe dos comandos normais. Pode até ser implementado como um binário externo. Aqui, [ apenas verá a e reclamará que não é realmente um inteiro.

$ [ a -eq 2 ] && echo yes
bash: [: a: integer expression expected
$ /usr/bin/[ a -eq 2 ] && echo yes
/usr/bin/[: invalid integer ‘a’

Use apenas algo como

a=asdf
if [[ $a = *[^0-9]* ]]; then
    echo "'$a' isn't an integer"
fi

ou

a=asdf
case "$a" in 
    *[^0-9]*) echo "'$a' isn't an integer";;
esac

Aparentemente, ksh faz a avaliação aritmética de a e 1+1 , mesmo em [ a -eq 1+1 ] .

    
por 22.08.2018 / 15:05

Tags