2009-12-11 15:24:17 +0000 2009-12-11 15:24:17 +0000
302
302

Quelle est la différence entre l'exécution d'un script Bash et son approvisionnement ?

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

A
> ./myscript

B
> source myscript

Réponses (6)

369
369
369
2010-08-16 21:58:48 +0000

Sourcing un script va exécuter les commandes dans le processus shell current.

Exécution un script exécutera les commandes dans un nouveau processus shell.

Utilisez le source si vous voulez que le script modifie l'environnement de votre shell en cours d'exécution.

Si vous êtes toujours confus, veuillez lire ce qui suit.

Terminologie

Pour clarifier certaines confusions courantes concernant la syntaxe à exécuter et la syntaxe du source :

./myscript

Cela exécutera myscript à condition que le fichier soit exécutable et situé dans le répertoire courant. Le point et la barre oblique de tête (./) indiquent le répertoire courant. Ceci est nécessaire car le répertoire courant n'est généralement pas (et ne devrait généralement pas être) dans $PATH.

myscript

Ceci exécutera myscript si le fichier est exécutable et situé dans un répertoire quelconque dans $PATH.

source myscript

Cela exécutera myscript. Le fichier ne doit pas nécessairement être exécutable, mais il doit s'agir d'un script shell valide. Le fichier peut être dans le répertoire courant ou dans un répertoire dans $PATH.

. myscript

Ceci sera également source myscript. Cette “orthographe” est celle officielle telle que définie par POSIX . Bash a défini source comme un alias au point.

Démonstration

Considérons 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éfinie et nous sommes dans le répertoire home.

Maintenant, nous exécutons le fichier :

$ ./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éfinie et le répertoire de travail n'a pas changé.

La sortie du 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. Le shell current a engendré un nouveau shell pour exécuter le script. Le script s'exécute dans le nouveau shell et toutes les modifications de l'environnement prennent effet dans le nouveau shell. Une fois le script terminé, le nouveau shell est détruit. Toutes les modifications apportées à l'environnement dans le nouveau shell sont détruites avec le nouveau shell. Seul le texte de sortie est imprimé dans le shell actuel.

Maintenant nous source le fichier :

$ 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é.

L'approvisionnement du script ne crée pas de nouveau shell. Toutes les commandes sont exécutées dans le shell actuel et les modifications de l'environnement prennent effet dans le shell actuel.

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

Une autre démonstration

Envisager de suivre le script pid.sh :

#!/bin/sh
echo $$

(la variable spéciale $$ s'étend au PID du processus de l'interpréteur de commandes en cours d'exécution)

Imprimez d'abord le PID de l'interpréteur de commandes en cours :

$ echo $$
25009

Source du script :

$ source pid.sh
25009

Exécuter le script, noter le PID :

$ ./pid.sh
25011

Source à nouveau :

$ source pid.sh
25009

Exécuter à nouveau :

$ ./pid.sh
25013

Vous pouvez voir que le sourcing du script s'exécute dans le même processus pendant 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 script. Le sourcing du script ne crée pas de nouveau shell et donc le PID reste le même.

Résumé

Tant la recherche de sources que l'exécution du script exécutent les commandes du script ligne par ligne, comme si vous aviez tapé ces commandes à la main ligne par ligne.

Les différences sont :

  • Lorsque vous exécutez le script, vous ouvrez un nouveau shell, tapez les commandes dans le nouveau shell, copiez la sortie sur votre shell actuel, puis fermez le nouveau shell. Toute modification de l'environnement ne prendra effet que dans le nouveau shell et sera perdue une fois le nouveau shell fermé.
  • Lorsque vous sourcez le script, vous tapez les commandes dans votre shell current. Toute modification de l'environnement prendra effet et restera dans votre shell actuel.

Utilisez le source si vous voulez que le script change l'environnement dans votre shell actuel. utilisez execute sinon.


Voir aussi :

23
23
23
2009-12-11 15:35:56 +0000

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

L'approvisionnement d'un script signifie qu'il est analysé et exécuté par le shell actuel lui-même. C'est comme si vous aviez tapé le contenu du script. Pour cette raison, le script source ne doit pas nécessairement être exécutable. Mais il doit être exécutable si vous l'exécutez, bien sûr.

Si vous avez des arguments de position dans le shell actuel, ils sont inchangés.

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

echo a $*

et j'en ai un :

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

j'obtiens quelque chose comme

a Fri Dec 11 07:34:17 PST 2009

Alors que :

$ set `date`
$ ./a.sh

me donne :

a

Espérant que cela aide.

9
9
9
2009-12-11 15:27:08 +0000

Le sourcing est essentiellement le même que de taper chaque ligne du script à l'invite de commande, une à la fois…

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

6
6
6
2012-02-23 07:27:43 +0000

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

5
5
5
2009-12-11 15:25:38 +0000

Le sourcing vous permet d'obtenir toutes les variables supplémentaires définies dans le script.
Donc, si vous avez des configurations ou des définitions de fonctions, vous devez sourcer et ne pas exécuter. Les exécutions sont indépendantes de l'environnement des parents.

2
2
2
2015-03-27 14:04:20 +0000

La commande source exécute le script fourni (la permission d'exécution n'est pas obligatoire** ) dans l'environnement de l'interpréteur de commandes courant, tandis que la commande ./ exécute le script exécutable fourni dans un nouveau interpréteur de commandes.

Aussi, vérifiez cette réponse par exemple : https://superuser.com/a/894748/432100