Je peux définir les fonctions bash
en utilisant ou en omettant le mot clé function
. Y a-t-il une différence?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Les deux appels aux fonctions foo
et bar
réussissent et je ne vois aucune différence. Je me demande donc si c'est juste pour améliorer la lisibilité, ou s'il y a quelque chose qui me manque ...
BTW dans d'autres shells comme dash
(/bin/sh
est lié à dash
dans debian/ubuntu), il échoue lors de l'utilisation du mot clé function
.
Il n'y a pas de différence AFAIK, à part le fait que la deuxième version est plus portable.
Le mot clé function
a été introduit dans ksh . Le traditionnel Bourne Shell n'avait que la syntaxe foo ()
, et POSIX standardise uniquement la foo ()
syntaxe.
Dans ATT ksh (mais pas pdksh), il existe quelques différences entre les fonctions définies par function
et les fonctions définies avec la syntaxe Bourne/POSIX. Dans les fonctions définies par function
, le mot clé typeset
déclare une variable locale: une fois la fonction terminée, la valeur de la variable est réinitialisée à ce qu'elle était avant d'entrer dans la fonction. Avec la syntaxe classique, les variables ont une portée globale, que vous utilisiez typeset
ou non.
$ ksh -c 'a=global; f () { typeset a=local; }; f; echo $a'
local
$ ksh -c 'a=global; function f { typeset a=local; }; f; echo $a'
global
Une autre différence dans ksh est que les fonctions définies avec le mot clé function
ont leur propre contexte d'interruption. Les interruptions définies en dehors de la fonction sont ignorées lors de l'exécution de la fonction, et les erreurs fatales à l'intérieur de la fonction ne quittent que la fonction et non du script entier. De plus, $0
Est le nom de la fonction dans une fonction définie par function
mais le nom du script dans une fonction définie avec ()
.
Pdksh n'émule pas ATT ksh. Dans pdksh, typeset
crée des variables de portée locale quelle que soit la fonction, et il n'y a pas d'interruptions locales (bien que l'utilisation de function
fasse quelques différences mineures - voir la page de manuel pour plus de détails).
Bash et zsh ont introduit le mot clé function
pour la compatibilité avec ksh. Cependant, dans ces shells, function foo { … }
Et foo () { … }
sont strictement identiques, tout comme les extensions bash et zsh function foo () { … }
. Le mot clé typeset
déclare toujours des variables locales (sauf avec -g
Bien sûr), et les traps ne sont pas locaux (vous pouvez obtenir des traps locaux dans zsh en définissant l'option local_traps
).
foo() any-command
est la syntaxe Bourne prise en charge par tout shell de type Bourne mais bash
, yash
et les versions récentes de posh
(qui ne prennent en charge que les commandes composées). (les implémentations Bourne Shell et AT&T de ksh
ne supportent pas foo() any-command > redirections
sauf si any-command
est une commande composée).
foo() any-compound-command
(exemples de commandes composées: { cmd; }
, for i do echo "$i"; done
, (cmd)
... la plus utilisée étant { ...; }
)
est la syntaxe POSIX prise en charge par tout shell de type Bourne et celle que vous souhaitez généralement utiliser.
function foo { ...; }
est la syntaxe Korn Shell, antérieure à la syntaxe Bourne. N'utilisez celui-ci que si vous écrivez spécifiquement pour la mise en œuvre AT&T de Korn Shell et avez besoin du traitement spécifique qu'il y reçoit. Cette syntaxe n'est pas POSIX, mais est prise en charge par bash
, yash
et zsh
pour la compatibilité avec le shell Korn à travers ces shells (et la base basée sur pdksh
variantes du Korn Shell) ne le traitent pas différemment de la syntaxe standard.
function foo () { ...; }
est la syntaxe de no Shell et ne doit pas être utilisé . Il est uniquement pris en charge par accident par bash
, yash
, zsh
et les variantes basées sur pdksh
du Korn Shell. Soit dit en passant, c'est aussi la syntaxe de la fonction awk
.
Si nous continuons à descendre la liste ésotérique,
function foo() other-compound-command
(comme function foo() (subshell)
ou function foo() for i do; ... done
) est encore pire. Il est supporté par bash
, yash
et zsh
, mais pas ksh, même les variantes basées sur pdksh
.
Tandis que:
function foo() simple command
est uniquement pris en charge par zsh
.
Sémantiquement, ces deux formes sont équivalentes dans Bash.
Depuis la page de manuel:
Les fonctions du shell sont déclarées comme suit:
name () compound-command [redirection] function name [()] compound-command [redirection]
Ceci définit une fonction nommée
name
. Le mot réservé fonction est facultatif. Si la fonction mot réservé est fourni, les parenthèses sont facultatives.
EDIT: Je viens de remarquer que cette question est balisée posix
. Dans POSIX sh
, le mot clé function
n'est pas utilisé (bien qu'il soit réservé).
Plusieurs autres ont répondu correctement maintenant, mais voici mon résumé concis:
La deuxième version est portable et est susceptible de fonctionner avec de nombreux shells standard (en particulier POSIX).
La première version ne fonctionnera qu'avec bash, mais vous pouvez omettre les parenthèses après le nom de la fonction.
Sinon, ils représentent des entités identiques après que bash les ait interprétés.