Renvoyer une valeur dune fonction bash

Jai une fonction qui renvoie 1 si le nombre est un nombre valide à dix chiffres:

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 } 

Il est appelé par:

if [[ $(valNum $num) -eq 1 ]]; then #do something fi 

La fonction fonctionne bien si le numéro est valide mais montre la syntaxe erreur si vous entrez un nombre invalide.

Réponse

La réponse de @choroba « est correcte, mais cet exemple peut être plus clair:

valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi 

Cet exemple est un peu plus long (paramétrer $valNumResult puis interroger cette valeur), mais décrit plus explicitement ce qui se passe: que valNum() renvoie une valeur, et cette valeur peut être interrogée et testée.

PS Veuillez vous rendre service et renvoyer 0 pour true et non nul pour false. De cette façon, vous pouvez utiliser la valeur de retour pour indiquer « pourquoi nous avons échoué » en cas déchec.

Réponse

Les fonctions de bash ne peuvent renvoyer que des codes de sortie. La substitution de commande, à linverse, est utilisée pour obtenir la sortie standard dun commande ou fonction. Par conséquent, pour vérifier lindicateur renvoyé, vous navez pas besoin de la substitution:

if valNum "$num" ; then # ... fi 

Mais, pour que cela fonctionne, vous devez renvoyer 0 si le numéro est valide, et 1 si ce nest pas le cas (le code de sortie 0 signifie aucune erreur).

Commentaires

  • Je ne comprends pas. Dans lexemple 24.7 de tldp.org/LDP/abs/html/complexfunct.html , la fonction renvoie la valeur maximale et non le code de sortie. Bien que votre suggestion fonctionne, mais je ne suis pas en mesure de comprendre pourquoi cela fonctionne
  • puisque votre test consiste à savoir si lentrée est un entier valide à 10 chiffres ou non, cest-à-dire vrai ou faux, la fonction renvoie 0 ou 1. Lexemple de choroba ‘ fonctionne car if valnum "$num" équivaut à if valnum "$num" = 0 cest-à-dire  » si cest vrai « . La règle de base dans les scripts sh est que 0 = vrai / succès, non-zéro = faux / erreur.
  • BTW, que  » Guide avancé de script bash  » nest pas ‘ un très bon guide – il ‘ se trompe sur beaucoup de choses et encourage certaines mauvaises pratiques de script. la FAQ Bash à mywiki.wooledge.org/BashFAQ est une bien meilleure ressource.
  • voir unix.stackexchange.com/questions/12236/ …
  • votre fonction échoue car elle fait écho à la chaîne  » Nombre invalide « , et vous faites ensuite une comparaison numérique entre cette chaîne et le nombre 1 avec if [[ $(valNum $num) -eq 1 ]]

Réponse

Vous ne pouvez pas renvoyer un résultat arbitraire à partir dune fonction shell. Vous ne pouvez renvoyer quun code détat qui est un entier compris entre 0 et 255. (Bien que vous puissiez passer une valeur plus grande à return, il est tronqué modulo 256.) La valeur doit être 0 pour indiquer le succès et une valeur différente pour indiquer léchec; par convention, vous devez vous en tenir aux codes derreur entre 1 et 125, car les valeurs plus élevées ont une signification particulière (mauvaise commande externe pour 126 et 127, tuée par un signal pour des valeurs plus élevées).

Puisque vous retournez un résultat oui ou non ici, un code détat est approprié. Puisque flag semble indiquer un succès ou un échec, vous devez utiliser les valeurs conventionnelles de 0 pour le succès et 1 pour léchec (le contraire de ce que vous avez écrit). Vous pouvez alors utiliser votre fonction directement dans une instruction 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 

Si vous avez besoin de distinguer les codes déchec, appelez la fonction directement. Immédiatement après son retour, le code déchec est disponible dans $?. Vous pouvez ensuite le vérifier avec une déclaration de cas:

valNum "$num" case $? in … 

Si vous devez utiliser le code détat plus tard, enregistrez-le dans une autre variable avant $? est écrasé par la commande suivante.

valNum "$num" valNum_status=$? 

Ce que vous avez écrit na pas fonctionné car la substitution de commande $(…) se développe en sortie de la fonction, qui dans votre code est soit le message derreur, soit vide, jamais 1.

Si vous avez besoin pour passer plus dinformations quun code détat ne le permet hors des fonctions du shell, vous avez deux possibilités:

  • Imprimer du texte sur la sortie standard, et appeler la fonction dans une commande de substitution: $(valNum "$num")
  • Assignez à une ou plusieurs variables dans la fonction et lisez ces variables plus tard.

Réponse

Jai moi-même eu des résultats contradictoires dans ce domaine. Voici les résultats de mes expériences empiriques.Tout dabord, une «  théorie  » sur les commandes bash ou * nix:

  • SUCCESS == 0 … à savoir. aucun code détat derreur)
  • FAIL              ! = 0 …… un code détat

Exemple:

if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?" 

Résultat:

ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2 

Comme indiqué, la commande ls renvoie le code détat = 2. Lorsque vous essayez un répertoire valide, létat est zéro ( 0 ). Pas la même chose que presque toutes les autres langues.

rule # 1 – Rendre …

  • TRUE   == 0
  • FALSE! = 0

Nous devons nous rappeler que nous testons des codes derreur dans un Bash if instruction. Je configure des constantes, ou vous pouvez utiliser les commandes 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 

et la sortie:

Invalid Number Not lucky. 

Cependant, je vous suggère de donner nimporte quel «  up-vote « @Gilles parce que sa réponse est la bonne. Je voulais juste avoir un côté simpliste sur ePaper.

Encore une chose, le test Commande . Cela ressemble à:

[[ some-expression ]]; 

La plupart du temps. Et par exemple:

$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0 

Zéro (0) étant true . Pourquoi? Eh bien la page de manuel dit quun seul argument est «  true  » quand il est NOT-NULL.

références:

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *