source some_file
some_file:
doit ()
{
echo doit $1
}
export TEST=true
Si je source some_file la fonction "doit" et la variable TEST sont disponibles sur la ligne de commande. Mais en exécutant ce script:
script.sh:
#/bin/sh
echo $TEST
doit test2
Renvoie la valeur de TEST, mais génère une erreur sur la fonction inconnue "doit".
Puis-je "exporter" la fonction aussi, ou dois-je me procurer un fichier dans script.sh pour y utiliser la fonction?
Dans Bash, vous pouvez exporter des définitions de fonctions vers un sous-shell avec
export -f function_name
Par exemple, vous pouvez essayer cet exemple simple:
./script1
: #!/bin/bash
myfun() {
echo "Hello!"
}
export -f myfun
./script2
./script2
: #!/bin/bash
myfun
Ensuite, si vous appelez ./script1
vous verrez la sortie Bonjour!.
"Exporter" une fonction à l'aide de export -f
crée une variable d'environnement avec le corps de la fonction. Considérez cet exemple:
$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() { echo \'\"\ \ \$
}
Cela signifie que seul le Shell (juste Bash?) Pourra accepter la fonction. Vous pouvez également définir la fonction vous-même car le Bash ne considère que les envvars commençant par () {
comme fonction:
$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'
Si vous devez "exporter" cette variable sur SSH, vous avez vraiment besoin de la fonction sous forme de chaîne. Cela peut être fait avec l'option d'impression (-p
) pour les fonctions (-f
) du declare
intégré:
$ declare -pf fn
fn ()
{
echo \'\"\ \ \$
}
Ceci est très utile si vous avez du code plus complexe qui doit être exécuté via SSH. Considérez le script fictif suivant:
#!/bin/bash
remote_main() {
local dest="$HOME/destination"
tar xzv -C "$dest"
chgrp -R www-data "$dest"
# Ensure that newly written files have the 'www-data' group too
find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh user@Host "$(declare -pf remote_main); remote_main"
S'appuyant sur @ réponse de Lekensteyn ...
Si tu utilises declare -pf
il affichera toutes les fonctions précédemment définies dans le shell actuel vers STDOUT.
À ce stade, vous pouvez rediriger STDOUT où vous le souhaitez et, en fait, remplir les fonctions précédemment définies où vous le souhaitez.
La réponse suivante les placera dans une variable. Ensuite, nous faisons écho à cette variable plus l'invocation de la fonction que nous voulons exécuter dans le nouveau shell qui est généré en tant que nouvel utilisateur. Pour ce faire, nous utilisons Sudo
avec le -u
(aka. user
) et simplement lancer Bash (qui recevra le STDOUT canalisé comme entrée à exécuter).
Comme nous savons que nous allons d'un shell Bash à un shell Bash, nous savons que Bash interprétera correctement les fonctions définies par les shells précédents. La syntaxe devrait être correcte tant que nous passons d'un shell Bash de la même version à un nouveau shell Bash de la même version.
YMMV si vous vous déplacez entre différents shells ou entre des systèmes qui peuvent avoir différentes versions de Bash.
#!/bin/bash
foo() {
echo "hello from `whoami`"
}
FUNCTIONS=`declare -pf`; echo "$FUNCTIONS ; foo" | Sudo -u otheruser bash
# $./test.sh
# hello from otheruser
Vous ne pouvez pas exporter de fonctions, pas de la manière que vous décrivez. Le shell ne chargera que le ~/.bashrc
fichier au début d'un shell interactif (recherchez "Invocation" dans la page de manuel bash ).
Ce que vous pouvez faire est de créer une "bibliothèque" qui sera chargée au démarrage du programme:
source "$HOME/lib/somefile"
Et placez-y vos fonctions et paramètres non interactifs.
eval "$(declare -F | sed -e 's/-f /-fx /')"
exportera toutes les fonctions.
Je le fais beaucoup avant de démarrer un shell interactif dans un script pour me permettre de déboguer et de travailler dans le contexte du script tout en utilisant ses fonctions et ses variables.
Exemple:
eval "$(declare -F | sed -e 's/-f /-fx /')"
export SOME IMPORTANT VARIABLES AND PASSWORDS
bash -i
Les fonctions ne sont pas exportées vers des sous-processus. C'est pourquoi il existe des fichiers nommés .kshrc ou .bashrc: pour définir des fonctions qui devraient également être disponibles en sous-coquilles.
Si vous exécutez un script, les scripts. * Shrc ne sont normalement pas fournis. Vous devez coder cela explicitement, comme dans . ~/.kshrc
.
declare -x -f NAME
Plus d'informations
- f restreindre l'action ou l'affichage aux noms et définitions des fonctions - x pour faire exporter les NOMS
Eh bien, je suis nouveau sur Linux, mais vous pouvez essayer cela. Dans un fichier, appelons-le, 'tmp/general' vous construisez votre fonction:
func1(){
echo "func from general"
}
Dans votre script Shell, ajoutez:
. /tmp/general
et courir:
func1
Vous obtiendrez à l'écran: func from general
.