/ / Avaliando o valor de retorno da função bash como inteiro - bash, função, teste, comparação, retorno

Avaliando o valor de retorno da função bash como integer - bash, function, testing, comparison, return

Tenho tentado escrever uma função bash para verificar se uma variável é um inteiro. A função is_number no script abaixo faz essa verificação.

Porém, quando o executo (com um valor de teste de 1234), recebo a seguinte mensagem de erro:

./test_n2.sh: line 13: [: Checking 1234
1234: integer expression expected
n is not an integrer

Estou confuso: a função retorna $?, que em meus testes de uma linha com grep está corretamente definido como 0 para valores integrais. A comparação de inteiros no bloco principal é feita como ["$ retval" -eq 0], que AFAIK é a forma correta para testar inteiros.

Alguém pode ajudar por favor?

TIA.

#!/usr/bin/env bash

function is_number {
number=$1
echo "Checking $number"
echo $number | /bin/egrep "^[0-9]+$"
return $?
}

n=1234
retval=`is_number $n`

if [ "$retval" -eq 0 ]; then
echo n is an integer
exit 0
fi

echo n is not an integrer
exit 1

Respostas:

2 para resposta № 1

Quando você atribui uma variável usando crases ou $(...), ele obtém a saída padrão do comando. O valor de retorno de um comando é colocado na variável $?. Então você deve fazer:

is_number $n
retval=$?

Ou você pode simplesmente escrever:

if is_number $n; then
echo n is an integer
exit 0
fi

0 para resposta № 2

Você não precisa grep para isso, o bash sozinho fará o trabalho com alegria e de forma mais eficiente:

is_number() {
# Check if $1 only consists of digits
[[ $1 = +([[:digit:]]) ]]
}

Então você pode usá-lo como:

if is_number 123; then
echo "it"s a number!"
else
echo "it"s not a number!"
fi

Use isso com a seguinte advertência: se você precisar fazer aritmética, esteja ciente de que os zeros à esquerda forçarão o bash a interpretar a string como um número na raiz 8. Portanto, o seguinte é um erro:

a=09
if is_number "$a"; then
echo $((a+1));
else
echo "Not a number"
fi

Portanto, seu snippet é melhor escrito como:

#!/usr/bin/env bash

shopt -s extglob
is_number() {
# Check if $1 only consists of digits
[[ $1 = +([[:digit:]]) ]]
}

n=1234
if is_number "$n"; then
echo "n is an integer"
exit 0
else
echo "n is not an integer"
exit 1
fi

ou se você precisar salvar o valor de retorno da função is_number:

#!/usr/bin/env bash

shopt -s extglob
is_number() {
# Check if $1 only consists of digits
[[ $1 = +([[:digit:]]) ]]
}

n=1234
is_number "$n"
ret=$?
if ((ret==0)); then
echo "n is an integer"
else
echo "n is not an integer"
fi

exit "$ret"