Dites que jai une fonction bash comme ceci:
gmx(){ echo "foo"; }
cette fonction sera implicitement renvoie la valeur de sortie de la commande echo
, ou est-il nécessaire dutiliser return?
gmx(){ echo "foo"; return $? }
Je suppose que la manière bash fonctionne, le statut de sortie de la commande finale de la fonction bash est celui qui est « retourné », mais pas sûr à 100%.
Réponse
return
fait un retour explicite depuis une fonction shell ou » dot script « (un script source). Si return
nest pas exécuté, un retour implicite est effectué à la fin de la fonction shell ou du script dot.
Si return
est exécuté sans paramètre, cela équivaut à renvoyer le statut de sortie de la dernière commande exécutée.
Cest ainsi que return
fonctionne dans tous les POSIX shells.
Par exemple,
gmx () { echo "foo" return "$?" }
équivaut donc à
gmx () { echo "foo" return }
qui est identique à
gmx () { echo "foo" }
En général, il est très rare que vous ayez besoin dutiliser $?
du tout. Il nest vraiment nécessaire que si vous devez lenregistrer pour une utilisation future, par exemple si vous devez rechercher sa valeur plusieurs fois (auquel cas vous attribueriez sa valeur à une variable et effectuer une série de tests sur cette variable).
Commentaires
Réponse
De la page de manuel bash(1)
:
Lorsquelle est exécutée, létat de sortie dune fonction est létat de sortie de la dernière commande exécutée dans le corps.
Commentaires
- à droite, et un corollaire pourrait être que linstruction de retour nest rien dautre que létat de sortie?
- Je suppose que
return
est une commande intégrée – bien quereturn 1
soit différent deexit 1
, etc. donc - » return [n]: Provoque larrêt de lexécution dune fonction et renvoie la valeur spécifiée par n à son appelant. Si n est omis, le statut de retour est celui de la dernière commande exécutée dans le corps de la fonction. » (ibid) Donc,
return
force létat de sortie dune fonction à une valeur spécifique si elle est spécifiée. - @AlexandwrMills Oui,
return
etexit
sont tous deux intégrés, sauf quereturn
ne peut être utilisé que dans la fonction. Vous pouvez ‘ terminer un script avecreturn
. Létat de sortie est la valeur renvoyée par la commande.return
est une commande qui renvoie cette valeur. Ainsi, linstruction de retour » nest rien de plus que létat de sortie » nest tout simplement pas tout à fait exact. Lun est une valeur, lautre est la commande plus la valeur. - @AlexanderMills,
return
renvoie de la fonction,exit
quitte tout le shell. Il ‘ est exactement le même que dans, disons C avecreturn
vsexit(n)
, oureturn
vssys.exit()
en Python.
Réponse
Je « vais juste ajouter quelques notes de prudence aux réponses déjà fournies:
-
Même si
return
a une signification très particulière pour le shell, dun point de vue syntaxique, il sagit dune commande interne du shell et dune instruction de retour est analysée comme toute autre commande simple. Cela signifie donc que, comme dans largument de toute autre commande,$?
sil nest pas entre guillemets, serait soumis à split + globVous devez donc citer cela
$?
pour léviter:return "$?"
-
return
naccepte généralement aucune option (ksh93
« s accepte les--help
,--man
,--author
… cependant). Le seul argument attendu (facultatif) est le code de retour. La plage des codes de retour acceptés varie du shell au shell, et si une valeur en dehors de 0..255 est correctement reflétée dans
varie également dun shell à lautre. Voir Code de sortie par défaut lorsque le processus est terminé? pour plus de détails à ce sujet.
La plupart des shells acceptent les nombres négatifs (après tout, largument passé à lappel système _exit()
/ exitgroup()
est un int
, donc avec des valeurs englobant au moins – 2 31 à 2 31 -1, il est donc logique que les shells acceptent la même plage pour ses fonctions).
La plupart des shells utilisent le waitpid()
et co. API pour récupérer cet état de sortie, mais auquel cas, il est tronqué à un nombre compris entre 0 et 255 lorsquil est stocké dans $?
. Même en appelant une fonction nimplique pas de générer un processus et utilisé waitpid()
pour récupérer son statut de sortie car tout est fait dans le même processus, de nombreux shells imitent également que waitpid()
comportement lors de lappel de fonctions. Cela signifie que même si vous appelez return
avec une valeur négative, $?
contiendra un nombre positif.
Maintenant, parmi les shells dont return
accepte les nombres négatifs (ksh88, ksh93, bash, zsh, pdksh et dérivés autres que mksh, yash), il y a quelques ( pdksh et yash) qui en ont besoin sous la forme return -- -123
sinon que -123
est considéré comme trois -1
, -2
, -3
options non valides.
Comme pdksh et ses de les rivaux (comme OpenBSD sh
ou posh
) conservent le nombre négatif dans $?
, cela signifie que faire return "$?"
échouerait lorsque $?
contient un nombre négatif (ce qui se produirait lorsque la dernière commande dexécution était une fonction qui retournait un nombre négatif ).
Donc, return -- "$?"
serait mieux dans ces shells. Cependant, notez que bien que supportée par la plupart des shells, cette syntaxe nest pas POSIX et en pratique non supportée par mksh
et les dérivés ash.
Donc, pour résumer, avec les shells basés sur pdksh, vous pouvez utiliser des nombres négatifs dans les arguments des fonctions, mais si vous le faites, return "$@"
ne fonctionnera pas. Dans dautres shells, return "$@"
fonctionnera et vous devriez éviter dutiliser des nombres négatifs (ou des nombres en dehors de 0..255) comme arguments pour return
.
Dans tous les shells que je connais, appeler return
depuis lintérieur dun sous-shell fonctionnant à lintérieur dune fonction provoquera la sortie du sous-shell (avec létat de sortie fourni le cas échéant ou celui de la dernière commande run), mais ne provoquera pas autrement un retour de la fonction (pour moi, il est difficile de savoir si POSIX vous donne cette garantie, certains soutiennent que exit
devrait être utilisé à la place des sous-shell de sortie fonctions internes). Par exemple
f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?"
affichera:
still inside f. Exit status: 3 f exit status: 0
Réponse
Oui, la valeur de retour implicite dune fonction est létat de sortie du dernier exécuté Commande . Cela est également vrai à tout moment de tout script shell. À tout moment de la séquence dexécution du script, létat de sortie actuel est létat de sortie de la dernière commande exécutée. Même commande exécutée dans le cadre dune affectation de variable: var=$(exit 34)
. La différence avec les fonctions est qu’une fonction peut changer l’état de sortie à la fin de l’exécution de la fonction.
L’autre façon de changer le «statut de sortie actuel» est de démarrer un sous-shell et de le quitter avec tout état de sortie nécessaire:
$ $(exit 34) $ echo "$?" 34
Et oui, létat de sortie expansion doivent être cités:
$ IFS="123" $ $(exit 34) $ echo $? 4
Un (exit 34)
fonctionne également.
Certains peuvent argumenter quune construction plus robuste devrait être $(return 34)
, et quune sortie devrait « quitter » le script en cours dexécution. Mais $(return 34)
ne fonctionne pas avec aucune version de bash. Donc, ce nest pas portable.
Le moyen le plus sûr de définir un statut de sortie est de lutiliser tel quil a été conçu pour fonctionner, définir et return
à partir dune fonction :
exitstatus(){ return "${1:-"$?"}"; }
Donc, à la fin dune fonction. cela équivaut exactement à navoir rien ou return
ou return "$?"
. La fin dune fonction na pas besoin de signifier la « dernière ligne de code dune fonction ».
#!/bin/sh exitstatus(){ a="${1:-"$?"}"; return "$a"; } gmx(){ if [ "$1" = "one" ]; then printf "foo "; exitstatus 78 return "$?" elif [ "$1" = "two" ]; then printf "baz "; exitstatus 89 return else printf "baz "; exitstatus 90 fi }
Affiche:
$ ./script foo 78 baz 89 baz 90
La seule utilisation pratique de "$?"
est soit dimprimer sa valeur: echo "$?"
, soit de stocker dans une variable (car il sagit dune valeur éphémère et change à chaque commande exécutée): exitstatus=$?
(noubliez pas de citer la variable dans les commandes comme export EXITSTATUS="$?"
.
Dans la commande return
, la plage de valeurs valide va généralement de 0 à 255, mais sachez que les valeurs de 126 + n
sont utilisés par certains shells pour signaler létat de sortie spécial, donc, la recommandation générale est dutiliser 0-125.
return
est celui des fonctions définies commef() (...; cmd; return)
, cela empêche loptimisation que font quelques shells dexécuter lecmd
dans le même processus que le sous-shell. Avec de nombreux shells, cela signifie également que létat de sortie de la fonction ne ‘ t porte pas linformation quecmd
a été tué quand il a (la plupart des shells peuvent de toute façon ‘ récupérer ces informations).sh
ouposh
), vous ‘ avez besoin dereturn -- "$?"
sil y avait un chance que la dernière commande soit une fonction qui a renvoyé un nombre négatif.mksh
(également basé sur pdksh) interdit aux fonctions de renvoyer des valeurs négatives.return x
fonctionne différemment deexit x
… la seule chose que je sais est quereturn x
ne quittera pas le processus en cours.return
est utilisé pour retourner à partir dune fonction ou dun script dot.exit
fait quelque chose de complètement différent (met fin à un processus).