web-dev-qa-db-fra.com

Puis-je appeler une fonction d'un script Shell à partir d'un autre script Shell?

J'ai 2 scripts Shell.

Le second script Shell contient les fonctions suivantes second.sh

func1 
func2

Le premier.sh appellera le second script Shell avec quelques paramètres et appellera func1 et func2 avec d’autres paramètres spécifiques à cette fonction.

Voici l'exemple de ce dont je parle

second.sh

val1=`echo $1`
val2=`echo $2`

function func1 {

fun=`echo $1`
book=`echo $2`

}

function func2 {

fun2=`echo $1`
book2=`echo $2`


}

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery

Comment puis-je y arriver?

53
avirup

Refactoriser votre script second.sh comme ceci:

function func1 {
   fun=$1
   book=$2
   printf "fun=%s,book=%s\n" "${fun}" "${book}"
}

function func2 {
   fun2=$1
   book2=$2
   printf "fun2=%s,book2=%s\n" "${fun2}" "${book2}"
}

Et appelez ensuite ces fonctions à partir du script first.sh comme ceci:

source ./second.sh
func1 love horror
func2 ball mystery

SORTIE:

fun=love,book=horror
fun2=ball,book2=mystery
98
anubhava

Vous ne pouvez pas appeler directement une fonction dans un autre script Shell.

Vous pouvez déplacer vos définitions de fonctions dans un fichier séparé, puis les charger dans votre script à l'aide de la commande ., comme suit:

. /path/to/functions.sh

Ceci interprétera functions.sh comme si son contenu était réellement présent dans votre fichier à ce stade. Il s'agit d'un mécanisme commun pour la mise en œuvre de bibliothèques partagées de fonctions Shell.

22
larsks

Le problème

La réponse actuellement acceptée ne fonctionne que dans des conditions importantes. /foo/bar/first.sh donné

function func1 {  
   echo "Hello $1"
}

et /foo/bar/second.sh

#!/bin/bash

source ./second.sh
func1 World

cela ne fonctionne que si le first.sh est exécuté à partir du même répertoire que le first.sh. C'est à dire. Si le chemin de travail actuel de Shell est /foo, la commande de tentative d'exécution 

cd /foo
./bar/first.sh

erreur d'impression:

/foo/bar/first.sh: line 4: func1: command not found

En effet, le source ./second.sh est relatif au chemin de travail actuel, pas au chemin du script. Par conséquent, une solution pourrait consister à utiliser le sous-shell et à exécuter

(cd /foo/bar; ./first.sh)

Solution plus générique

/foo/bar/first.sh donné

function func1 {  
   echo "Hello $1"
}

et /foo/bar/second.sh

#!/bin/bash

source $(dirname "$0")/second.sh

func1 World

puis 

cd /foo
./bar/first.sh

empreintes

Hello World

Comment ça marche

  • $0 renvoie le chemin relatif ou absolu du script exécuté
  • dirname renvoie le chemin relatif du répertoire dans lequel le script $ 0 existe 
  • $( dirname "$0" ) la commande dirname "$0" renvoie le chemin relatif du répertoire du script exécuté, qui est ensuite utilisé comme argument de la commande source 
  • /second.sh ajoute simplement le nom du script shell importé 
  • source charge le contenu du fichier spécifié dans currentShell
8
Patrik Stas

Si vous définissez 

    #!/bin/bash
        fun1(){
          echo "Fun1 from file1 $1"
        }
fun1 Hello
. file2 
fun1 Hello
exit 0

dans fichier1 (chmod 750 fichier1) et fichier2

   fun1(){
      echo "Fun1 from file2 $1"
    }
    fun2(){
      echo "Fun1 from file1 $1"
    }

et lancez ./fichier2, vous obtiendrez Fun1 à partir de fichier1 Bonjour Fun1 à partir de fichier2 Bonjour Surprise !!! Vous écrasez fun1 dans fichier1 avec fun1 à partir de fichier2 ... Pour ne pas le faire, vous devez

declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello

il enregistre votre définition précédente pour fun1 et le restaure avec le nom précédent en supprimant celui dont vous n'avez pas besoin. 1. Chaque fois que vous importez des fonctions à partir d'un autre fichier, vous pouvez vous rappeler de deux aspects

  1. vous pouvez écraser les noms existants avec les mêmes noms (si c'est ce que vous voulez, vous devez les conserver comme décrit ci-dessus)
  2. importer tout le contenu du fichier d'importation (fonctions et variables globales également) Faites attention! C'est une procédure dangereuse
0
Anatoly