Retornando um valor de uma função bash

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

  • Não entendi. No exemplo 24.7 em tldp.org/LDP/abs/html/complexfunct.html , a função está retornando o valor máximo e não o código de saída. Embora sua sugestão esteja funcionando, mas eu não consigo entender por que está funcionando
  • já que seu teste é para descobrir se a entrada é um número inteiro de 10 dígitos válido ou não, ou seja, verdadeiro ou falso, a função retorna 0 ou 1. choroba ‘ s exemplo funciona porque if valnum "$num" é equivalente a if valnum "$num" = 0 ou seja, ” se for verdadeiro “. A regra básica em scripts sh é que 0 = verdadeiro / sucesso, diferente de zero = falso / erro.
  • BTW, que ” Guia avançado de script Bash ” não é ‘ um guia muito bom – ele ‘ está errado sobre muitas coisas e incentiva algumas práticas de script ruins. a FAQ do Bash em mywiki.wooledge.org/BashFAQ é um recurso muito melhor.
  • consulte unix.stackexchange.com/questions/12236/ …
  • sua função está falhando porque está ecoando a string ” Número inválido “, e você então fazendo uma comparação numérica entre essa string e o número 1 com if [[ $(valNum $num) -eq 1 ]]

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:

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *