Je travaille avec un script bash et je veux exécuter une fonction pour imprimer une valeur de retour:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Lorsque j'exécute fun2
, il n'imprime pas "34". pourquoi est-ce le cas?
bash
function
return-value
Mindia
la source
la source
return
dans votre cas est essentiellement le même que celuiexit code
qui va de0 - 255
. Utilisezecho
comme suggéré par @septi. Les codes de sortie peuvent être capturés avec$?
.function a() { echo 34; }
function b() { while read data; do echo $data ; done ;}
a | b
Réponses:
Bien que bash ait une
return
instruction, la seule chose que vous pouvez spécifier avec elle est le propreexit
statut de la fonction (une valeur entre0
et255
, 0 signifiant "succès"). Cereturn
n'est donc pas ce que vous voulez.Vous voudrez peut-être convertir votre
return
instruction enecho
instruction - de cette façon, la sortie de votre fonction pourrait être capturée à l'aide d'$()
accolades, ce qui semble être exactement ce que vous voulez.Voici un exemple:
Une autre façon d'obtenir la valeur de retour (si vous voulez simplement renvoyer un entier 0-255) est
$?
.Notez également que vous pouvez utiliser la valeur de retour pour utiliser la logique booléenne comme
fun1 || fun2
ne s'exécutera quefun2
sifun1
renvoie une0
valeur. La valeur de retour par défaut est la valeur de sortie de la dernière instruction exécutée dans la fonction.la source
fun1
, puis la valeur de retour est stockée dans$?
. Bien que je ne recommanderais pas de faire ça ...$?
?||
construction, un code de sortie de 0 est considéré comme un succès et donc "vrai". Non nul est une erreur et donc faux. Considérezfun1 || fun2
comme un raccourci pour "si fun1 retourne le succès ou fun2 retourne le succès" plutôt qu'un opérateur sur les valeurs de retour réelles elles-mêmes.$(...)
capture le texte envoyé à stdout par la commande contenue dans.return
ne sort pas sur stdout.$?
contient le code de résultat de la dernière commande.la source
return
est utilisé pour définir$?
qui est leexit status
. Dans l'exemple ci - dessus,fun1
« sexit status
seraient34
. Notez$(...)
également que capture également stderr en plus de stdout à partir de la commande spécifiée.Les fonctions dans Bash ne sont pas des fonctions comme dans une autre langue; ce sont en fait des commandes. Les fonctions sont donc utilisées comme s'il s'agissait de binaires ou de scripts extraits de votre chemin. Du point de vue de la logique de votre programme, il ne devrait y avoir vraiment aucune différence.
Les commandes shell sont connectées par des canaux (ou flux), et non par des types de données fondamentaux ou définis par l'utilisateur, comme dans les "vrais" langages de programmation. Il n'y a rien de tel qu'une valeur de retour pour une commande, peut-être principalement parce qu'il n'y a pas de véritable moyen de la déclarer. Cela peut se produire sur la page de manuel ou sur la
--help
sortie de la commande, mais les deux ne sont lisibles que par l'homme et sont donc écrits au vent.Lorsqu'une commande veut obtenir une entrée, elle la lit à partir de son flux d'entrée ou de la liste d'arguments. Dans les deux cas, les chaînes de texte doivent être analysées.
Lorsqu'une commande veut renvoyer quelque chose, elle doit la retrouver
echo
dans son flux de sortie. Une autre façon souvent pratiquée consiste à stocker la valeur de retour dans des variables globales dédiées. L'écriture dans le flux de sortie est plus claire et plus flexible, car elle peut également prendre des données binaires. Par exemple, vous pouvez retourner facilement un BLOB:Comme d'autres l'ont écrit dans ce fil, l'appelant peut également utiliser la substitution de commandes
$()
pour capturer la sortie.Parallèlement, la fonction "retournerait" le code de sortie de
gpg
(GnuPG). Considérez le code de sortie comme un bonus que les autres langues n'ont pas, ou, selon votre tempérament, comme un "Schmutzeffekt" de fonctions shell. Ce statut est, par convention, 0 en cas de succès ou un entier compris entre 1 et 255 pour autre chose. Pour que cela soit clair:return
(commeexit
) ne peut prendre qu'une valeur comprise entre 0 et 255, et des valeurs autres que 0 ne sont pas nécessairement des erreurs, comme cela est souvent affirmé.Lorsque vous ne fournissez pas de valeur explicite,
return
le statut provient de la dernière commande dans une instruction / fonction / commande Bash, etc. Il y a donc toujours un statut etreturn
c'est juste un moyen facile de le fournir.la source
L'
return
instruction définit le code de sortie de la fonction, de la même manièreexit
que pour tout le script.Le code de sortie de la dernière commande est toujours disponible dans la
$?
variable.la source
Le problème avec les autres réponses est qu'elles utilisent soit un global, qui peut être écrasé lorsque plusieurs fonctions sont dans une chaîne d'appel, soit
echo
que votre fonction ne peut pas générer d'informations de diagnostic (vous oublierez que votre fonction fait cela et le "résultat", c'est-à-dire retour valeur, contiendra plus d'informations que ce que votre appelant attend, ce qui conduit à un bug étrange), oueval
qui est beaucoup trop lourd et hacky.La bonne façon de le faire est de placer les éléments de niveau supérieur dans une fonction et d'utiliser une
local
règle de portée dynamique avec bash. Exemple:Cette sorties
La portée dynamique signifie que cela
ret_val
pointe vers un objet différent selon l'appelant! Ceci est différent de la portée lexicale, qui est utilisée par la plupart des langages de programmation. Il s'agit en fait d' une fonctionnalité documentée , facile à manquer, et pas très bien expliquée, voici la documentation pour elle (c'est moi qui souligne):Pour quelqu'un avec un fond C / C ++ / Python / Java / C # / javascript, c'est probablement le plus grand obstacle: les fonctions en bash ne sont pas des fonctions, ce sont des commandes et se comportent comme telles: elles peuvent sortir vers
stdout
/stderr
, elles peuvent diriger / out, ils peuvent retourner un code de sortie. Fondamentalement, il n'y a aucune différence entre la définition d'une commande dans un script et la création d'un exécutable qui peut être appelé à partir de la ligne de commande.Donc au lieu d'écrire votre script comme ceci:
écrivez-le comme ceci:
où
main()
déclareret_val
aslocal
et toutes les autres fonctions renvoient des valeurs viaret_val
.Voir aussi la question Unix et Linux suivante: Portée des variables locales dans les fonctions shell .
Une autre solution, peut-être encore meilleure selon la situation, est celle publiée par ya.teck qui utilise
local -n
.la source
Une autre façon d'y parvenir est les références de nom (nécessite Bash 4.3+).
la source
-n <name>=<reference>
fait: fait de la variable nouvellement créée une référence à une autre pointée par<reference>
. D'autres affectations<name>
sont effectuées sur la variable référencée.J'aime faire ce qui suit si je cours dans un script où la fonction est définie:
J'aime ça, car je peux ensuite inclure des déclarations d'écho dans mes fonctions si je veux
la source
En complément des excellents articles des autres, voici un article résumant ces techniques:
Renvoyer des valeurs à partir de fonctions Bash
la source
Git Bash sur Windows à l' aide de tableaux pour plusieurs valeurs de retour
CODE DE BASE:
PRODUCTION ATTENDUE:
la source