458 votes

Quelle est la différence entre l'exécution d'un script en Bash et le sourcing ?

Quelle est la différence entre exécuter un script Bash comme A et sourcer un script Bash comme B ?

A
> ./myscript

B
> source myscript

3 votes

Vous pourriez lire ceci : bash.cyberciti.biz/guide/commande_source

0 votes

575voto

Lesmana Points 18245

Le sourcing et l'exécution du script exécuteront les commandes du script ligne par ligne, comme si vous aviez tapé ces commandes à la main ligne par ligne.

Les différences sont les suivantes :

  • Quand vous exécuter le script que vous ouvrez une nouveau Shell, tapez les commandes dans la nouvelle Shell, recopiez la sortie dans votre Shell actuelle, puis fermez la nouvelle Shell. Tout changement d'environnement ne prendra effet que dans la nouvelle Shell et sera perdu une fois que la nouvelle Shell sera fermée.
  • Quand vous source le script que vous tapez les commandes dans votre actuel Shell. Toute modification de l'environnement prendra effet et restera dans votre Shell actuel.

l'"environnement" est constitué de choses comme le répertoire de travail actuel et les variables d'environnement. également les paramètres de Shell (entre autres l'historique et les fonctionnalités de complétion). il y en a plus mais ce sont les plus visibles.

Utilisez source si vous voulez que le script change l'environnement dans votre script en cours d'exécution. utilisez execute sinon.

Si vous voulez plus de détails, lisez la suite.

Terminologie

Afin de clarifier certaines confusions courantes concernant la syntaxe à exécuter et la syntaxe à source.

Syntaxe à exécuter :

./myscript

Cela permettra exécuter myscript à condition que le fichier soit exécutable et situé dans le répertoire courant. Le point et la barre oblique ( ./ ) désigne le répertoire courant. Ceci est nécessaire parce que le répertoire courant n'est généralement pas (et ne devrait généralement pas être) dans $PATH .

myscript

Cela permettra exécuter myscript si le fichier est exécutable et se trouve dans un répertoire quelconque de l'application $PATH .

Syntaxe à la source :

source myscript

Cela permettra source myscript . Le fichier ne doit pas nécessairement être exécutable mais il doit être un Shell Shell valide. Le fichier peut être dans le répertoire courant ou dans un répertoire dans $PATH .

. myscript

Cela permettra également source myscript . Cette "orthographe" est l'orthographe officielle telle que définie par POSIX . Bash a défini source comme alias du point.

et par souci d'exhaustivité :

exec myscript

Cela mettra fin à la Shell actuelle et exécutera ensuite myscript à la place de la Shell terminée. Cela signifie que lorsque myscript est terminé, il n'y a pas de Shell à laquelle revenir. exec est puissant mais rarement nécessaire.

J'ai mis quelques liens à la fin pour plus d'informations sur ces sujets.

Démonstration

Pensez à myscript.sh avec le contenu suivant :

#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD

Avant d'exécuter le script, nous vérifions d'abord l'environnement actuel :

$ env | grep FOO
$ echo $PWD
/home/lesmana

La variable FOO n'est pas défini et nous sommes dans le répertoire d'origine.

Maintenant, nous exécuter le dossier :

$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Vérifiez à nouveau l'environnement :

$ env | grep FOO
$ echo $PWD
/home/lesmana

La variable FOO n'est pas défini et le répertoire de travail n'a pas changé.

La sortie script montre clairement que la variable a été définie et que le répertoire a été modifié. La vérification qui suit montre que la variable n'est pas définie et que le répertoire n'a pas été modifié. Que s'est-il passé ? Les modifications ont été effectuées dans un nouveau Shell.

El actuel Shell a engendré une nouveau Shell pour exécuter le Shell. Le Shell s'exécute dans le nouveau Shell et toutes les modifications de l'environnement prennent effet dans le nouveau Shell. Une fois le Shell terminé, la nouvelle Shell est détruite. Toutes les modifications de l'environnement dans la nouvelle Shell sont détruites avec la nouvelle Shell. Seul le texte de sortie est imprimé dans la Shell actuelle.

Maintenant, nous source le dossier :

$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Vérifiez à nouveau l'environnement :

$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir

La variable FOO est définie et le répertoire de travail a changé.

Le sourcing du script ne crée pas un nouveau script. Toutes les commandes sont exécutées dans la script actuelle et les modifications de l'environnement prennent effet dans la script actuelle.

Notez que dans cet exemple simple, la sortie de l'exécution est la même que le sourcing du script. Ce n'est pas nécessairement toujours le cas.

Une autre démonstration

Considérez le script suivant pid.sh :

#!/bin/sh
echo $$

(la variable spéciale $$ se développe vers le PID du processus Shell en cours d'exécution.)

Tout d'abord, imprimez le PID du Shell actuel :

$ echo $$
25009

Sourcez le script :

$ source pid.sh
25009

Exécutez le script, notez le PID :

$ ./pid.sh
25011

Source encore :

$ source pid.sh
25009

Exécutez à nouveau :

$ ./pid.sh
25013

Vous pouvez voir que le sourcing du script s'exécute dans le même processus alors que l'exécution du script crée un nouveau processus à chaque fois. Ce nouveau processus est le nouveau Shell qui a été créé pour l'exécution du Shell. Le sourcing du Shell ne crée pas un nouveau Shell et donc le PID reste le même.

Résumé

Recherche de fournisseurs un script exécutera les commandes de l'option actuel Shell processus. Les modifications de l'environnement prennent effet dans le Shell actuel.

Exécuter un script exécutera les commandes d'une nouveau Shell processus. Les modifications de l'environnement prennent effet dans le nouveau Shell et sont perdues lorsque le Shell est terminé et que le nouveau Shell est terminé.

Utilisez source si vous voulez que le script change l'environnement dans votre script en cours d'exécution. utilisez execute sinon.


Voir aussi :

7 votes

Une utilisation du sourcing consiste à créer une forme rudimentaire de fichier de configuration pour vos scripts. Vous commencez par définir diverses variables à des valeurs par défaut, et ensuite vous sourcez quelque chose comme myscript.conf - et ce scripts sourcé peut avoir des déclarations d'affectation qui remplacent les valeurs que vous voulez. Puisque le scripts sourcé ne commence pas par #/bin/bash, il n'est pas encouragé de l'exécuter directement.

0 votes

Donc, la source est en quelque sorte comme l'exécution dans une portée globale, et l'exécution crée une nouvelle portée locale. Peut-on étendre cela à une fonction dans un script ? pour exécuter une fonction (normalement) ou pour la "sourcer" ?

0 votes

L'appel d'une fonction Shell se comporte normalement comme un sourcing. L'appel d'une fonction Shell à l'intérieur d'un subshell se comporte comme un executing.

27voto

Alok Points 726

L'exécution d'un script le fait tourner dans un processus enfant séparé, c'est-à-dire qu'une instance séparée de script est invoquée pour traiter le script. Cela signifie que toute variable d'environnement, etc. définie dans le script. ne peut pas être mis à jour dans le Shell parent (courant).

Sourcer un script signifie qu'il est analysé et exécuté par le script courant lui-même. C'est comme si vous aviez tapé le contenu du script. Pour cette raison, le script qui est sourcé n'a pas besoin d'être exécutable. Mais il doit être exécutable si vous l'exécutez bien sûr.

Si vous avez des arguments positionnels dans le Shell actuel, ils sont inchangés.

Donc si j'ai un fichier a.sh contenant :

echo a $*

et je le fais :

$ set `date`
$ source ./a.sh

Je reçois quelque chose comme :

a Fri Dec 11 07:34:17 PST 2009

Considérant que :

$ set `date`
$ ./a.sh

me donne :

a

J'espère que cela vous aidera.

9 votes

Bien que cette réponse soit correcte à tous égards, je la trouve très difficile à comprendre car elle est démontrée à l'aide d'un autre concept (le réglage des paramètres de position), qui est, à mon avis, encore plus déroutant que la différence entre le sourcing et l'exécution elle-même.

10voto

abs Points 91

En plus de ce qui précède, l'exécution du script en tant que ./myscript requiert une autorisation d'exécution pour le fichier myscript alors que le sourcing ne requiert aucune autorisation d'exécution. C'est pourquoi chmod +x myscript n'est pas nécessaire avant source myscript

3 votes

Vrai, mais si c'est un problème, vous pouvez toujours exécuter bash myscript .

9voto

John Weldon Points 1551

Le sourcing revient essentiellement à taper chaque ligne du script à l'invite de commande, une par une...

L'exécution démarre un nouveau processus puis exécute chaque ligne du script, ne modifiant l'environnement actuel que par ce qu'il retourne.

5voto

Arkaitz Jimenez Points 173

En sourçant, vous obtenez toutes les variables supplémentaires définies dans le script.
Ainsi, si vous avez des configurations ou des définitions de fonctions, vous devez créer une source et non l'exécuter. Les exécutions sont indépendantes de l'environnement des parents.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X