Eu tenho uma função que retorna 1 se o número for um número válido de dez dígitos:
valNum() { flag=1 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=0 fi return $flag }
Ela está sendo chamada por:
if [[ $(valNum $num) -eq 1 ]]; then #do something fi
A função está funcionando bem se o número for válido, mas estiver mostrando a sintaxe erro se inserir um número inválido.
Resposta
A resposta de @choroba “está correta, mas este exemplo pode ser mais claro:
valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi
Este exemplo é um pouco mais longo (definindo $valNumResult
e depois consultando esse valor), mas descreve mais explicitamente o que acontece: que valNum()
retorna um valor e esse valor pode ser consultado e testado.
PS Faça um favor a si mesmo e devolva 0
para true
e diferente de zero para false
. Dessa forma, você pode usar o valor de retorno para indicar “por que falhamos” no caso de falha.
Resposta
As funções em bash só podem retornar códigos de saída. A substituição do comando, por outro lado, é usada para obter a saída padrão de um comando ou função. Portanto, para verificar o sinalizador retornado, você não precisa da substituição:
if valNum "$num" ; then # ... fi
Mas, para que funcione, você deve retornar 0 se o número é válido, e 1 se não for (código de saída 0 significa nenhum erro).
Comentários
Resposta
Você não pode retornar um resultado arbitrário de uma função shell. Você só pode retornar um código de status que seja um número inteiro entre 0 e 255. (Embora você possa passar um valor maior para return
, ele é o módulo truncado 256.) O valor deve ser 0 para indicar sucesso e um valor diferente para indicar falha; por convenção, você deve se ater a códigos de erro entre 1 e 125, pois os valores mais altos têm um significado especial (comando externo ruim para 126 e 127, morto por um sinal para valores mais altos).
Já que você está retornando um resultado sim ou não aqui, um código de status é apropriado. Como flag
parece indicar um sucesso ou falha, você deve usar os valores convencionais de 0 para sucesso e 1 para falha (o oposto do que você escreveu). Você pode então usar sua função diretamente em uma instrução if.
valNum () { local flag=0 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo 1>&2 "Invalid Number" flag=1 fi return $flag } if valNum "$num"; then #do something fi
Se você precisar discriminar entre códigos de falha, chame a função diretamente. Imediatamente após seu retorno, o código de falha está disponível em $?
. Você pode verificá-lo com uma instrução case:
valNum "$num" case $? in …
Se precisar usar o código de status mais tarde, salve-o em outra variável antes de $?
é sobrescrito pelo próximo comando.
valNum "$num" valNum_status=$?
O que você escreveu não funcionou porque a substituição do comando $(…)
se expande para a saída da função, que em seu código é a mensagem de erro ou vazia, nunca 1
.
Se você precisar para passar mais informações do que um código de status permite de funções de shell, você tem duas possibilidades:
- Imprimir algum texto na saída padrão e chamar a função em uma substituição de comando:
$(valNum "$num")
- Atribua a uma ou mais variáveis dentro da função e leia essas variáveis mais tarde.
Resposta
Eu mesmo tive resultados conflitantes nessa área. Aqui estão os resultados de minhas experiências empíricas.Em primeiro lugar, alguma “ teoria ” sobre os comandos bash ou * nix:
- SUCCESS == 0 … viz. sem código de status de erro)
- FALHA ! = 0 …… algum código de status
Exemplo:
if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?"
Resultado:
ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2
Conforme mostrado, o comando ls
retorna o código de status = 2. Quando você tenta um diretório válido, o status é zero ( 0 ). Diferente de quase todos os outros idiomas.
regra # 1 – Torne …
- VERDADEIRO == 0
- FALSO! = 0
Devemos lembrar que estamos testando códigos de erro em um Bash if
declaração. Eu configuro constantes ou você pode usar os comandos shell true
ou false
.
TRUE=0 FALSE=1 # valid number function # valNum() { flag=$TRUE if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=$FALSE fi return $flag } # later on ... # if validNum Abc then echo "Lucky number" else echo "Not lucky." fi
e saída:
Invalid Number Not lucky.
No entanto, sugiro que você dê qualquer “ voto positivo “@Gilles porque sua resposta é a correta. Eu só queria ver o lado simplista do ePaper.
Só mais uma coisa, o test
comando . Isso se parece com:
[[ some-expression ]];
Na maioria das vezes. E por exemplo:
$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0
Zero (0) sendo true . Porque? Bem, a página do manual diz que um único argumento é “ true ” quando não é NULL.
Referências:
if valnum "$num"
é equivalente aif valnum "$num" = 0
ou seja, ” se for verdadeiro “. A regra básica em scripts sh é que 0 = verdadeiro / sucesso, diferente de zero = falso / erro.if [[ $(valNum $num) -eq 1 ]]