web-dev-qa-db-fra.com

Exporter une fonction en shell

Dites-moi comment exporter une fonction dans le shell parent (bash, sh ou ksh) afin que la fonction soit disponible pour tous les processus enfants lancés depuis le processus parent

80
Sachin Chourasiya

La fonctionnalité export -f est spécifique à Bash:

parent

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

enfant

#!/bin/bash
echo $(plus1 $(($1 * $2)) )
98
Dennis Williamson

Dans sh, il est non possible d'exporter une fonction, comme noté par Charles Duffy .

7
anol

Si vous utilisez ksh ou zsh:

Vous pouvez utiliser la variable d'environnement FPATH, dans laquelle vous pouvez placer toutes vos fonctions.

Si FPATH est défini sur un interpréteur interactif et qu'aucune commande ou fonction est introuvable dans l'environnement Shell actuel ou dans PATH, les répertoires répertoriés ici sont recherchés pour l'existence d'un fichier nommé d'après la commande manquante. S'il en trouve un, il provient de l'environnement Shell actuel et doit définir la fonction.

Ainsi, vous pouvez placer toutes vos fonctions dans un emplacement dans FPATH, et les scripts enfants pourront également le trouver.

Vous pouvez utiliser la commande autoload dans les scripts Shell pour charger les fonctions requises:

autoload fun_a fun_b

Dans zsh, autoload est requis pour que FPATH puisse fonctionner. Dans ksh et ses proches parents, je pense que cela provoque simplement que les fonctions définies dans FPATH remplacent les commandes régulières de votre PATH, comme elles le seraient si elles étaient définies directement.

Quelques détails sur FPATH et autoload:

3

Si vous créez des sous-shell avec ( ), ils hériteront d'un instantané de toutes les définitions, paramètres et variables Shell.

Si vous les exécutez comme des programmes, vous pouvez mettre les définitions dans .bashrc.

Si vous essayez d'usurper un script existant en exécutant un wrapper ou en remplaçant une commande PATH, alors .bashrc fonctionnera en fonction des détails de l'exécution. Sinon, vous pouvez plutôt exécuter un script d'encapsulage qui effectue simplement un . ou source d'un fichier include qui définit les fonctions, puis fait la même chose avec le script Shell avec les commandes à substituer.

Le script wrapper peut ressembler à quelque chose comme:

script=$1
shift
. include.sh
. $script "$@"

L'idée est que le premier paramètre est le nom du script réel et que les paramètres restants sont les arguments, puis le script ci-dessus est exécuté à la place.

1
DigitalRoss
declare -x -f NAME

Plus d'informations

- f restreint l'action ou l'affichage aux noms de fonction et aux définitions 
- x pour exporter les NOM 
1
Steven Penny

Les fonctions ne sont pas exportables par nature. Cependant, vous pouvez exporter des chaînes, alors j'ai un petit truc ici:

func="$(typeset -f funcname)"
export func

Pour importer la fonction, redéfinissez-la à partir de la chaîne exportée:

# in subshell
eval "$func"
0
iBug