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
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
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.
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.
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.
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.
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 :
Utilisez le source si vous voulez que le script change l'environnement dans votre shell actuel. utilisez execute sinon.
Voir aussi :
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.
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.
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
.
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.
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