Quelle est la différence entre l’exécution d’un script Bash tel que A et la création d’un script Bash tel que B?
A
> ./myscript
B
> source myscript
Sourcing un script exécutera les commandes du processus actuel Shell.
L'exécution de un script exécutera les commandes dans un processus nouveau Shell.
Si vous êtes toujours confus, lisez la suite.
Pour clarifier une certaine confusion concernant la syntaxe à exécuter et la syntaxe à utiliser comme source:
./myscript
Ceci execute myscript
à condition que le fichier soit exécutable et situé dans le répertoire en cours. Le point et la barre oblique (./
) indiquent le répertoire en cours. Cela est nécessaire car le répertoire en cours ne figure généralement pas (et ne devrait normalement pas l'être) dans $PATH
.
myscript
Ceci execute myscript
si le fichier est exécutable et situé dans un répertoire de $PATH
.
source myscript
Ce sera source 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 en cours ou dans un répertoire dans $PATH
.
. myscript
Cela va aussi source myscript
. Cette "orthographe" est l'orthographe officielle définie par POSIX . Bash définit source
comme un alias pour le point.
Considérez 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 l'environnement actuel:
$ env | grep FOO
$ echo $PWD
/home/lesmana
La variable FOO
n'est pas définie et nous nous trouvons dans le répertoire de base.
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 indique clairement que la variable a été définie et que le répertoire a été modifié. La vérification montre ensuite que la variable n'est pas définie et que le répertoire n'est pas modifié. Qu'est-il arrivé? Les modifications ont été apportées dans un nouveau Shell. Le actuel Shell a généré un nouveau Shell pour exécuter le script. Le script est exécuté dans le nouveau shell et toutes les modifications apportées à 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 été modifié.
La création du script ne crée pas de nouveau shell. Toutes les commandes sont exécutées dans le shell actuel et les modifications apportées à l'environnement prennent effet dans le shell actuel.
Notez que dans cet exemple simple, le résultat de l'exécution est identique à l'obtention du script. Ce n'est pas forcément toujours le cas.
Envisagez de suivre le script pid.sh
:
#!/bin/sh
echo $$
(la variable spéciale $$
se développe en PID du processus Shell en cours d'exécution)
Imprimez d'abord le PID du shell actuel:
$ echo $$
25009
Source 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 constater que la recherche 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 créé pour l'exécution du script. La création du script ne crée pas de nouveau shell et le PID reste donc le même.
La recherche et l’exécution du script exécutent les commandes dans le script ligne par ligne, comme si vous les tapiez à la main, ligne par ligne.
Les différences sont:
Utilisez source si vous souhaitez que le script modifie l'environnement dans votre Shell en cours d'exécution. use exécute autrement.
Voir également:
L'exécution d'un script l'exécute dans un processus enfant distinct, c'est-à-dire qu'une instance distincte de Shell est appelée pour traiter le script. Cela signifie que toute variable d'environnement, etc., définie dans le script ne peut pas est mise à jour dans le Shell parent (actuel).
La création d'un script signifie qu'il est analysé et exécuté par le shell actuel. C'est comme si vous avez tapé le contenu du script. Pour cette raison, le script recherché 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 ne sont pas modifiés.
Donc, si j'ai un fichier a.sh
contenant:
echo a $*
et je fais:
$ set `date`
$ source ./a.sh
Je reçois quelque chose comme:
a Fri Dec 11 07:34:17 PST 2009
Tandis que:
$ set `date`
$ ./a.sh
donne moi:
a
J'espère que cela pourra aider.
sourcing est essentiellement la même chose que taper chaque ligne du script dans la commande Invite, une à la fois ...
L'exécution démarre un nouveau processus, puis exécute chaque ligne du script, en modifiant uniquement l'environnement actuel en fonction de ce qu'il retourne.
En plus de ce qui précède, l’exécution du script en tant que ./myscript
nécessite une autorisation d’exécution pour le fichier myscript, tandis que la recherche de sources n’exige aucune autorisation d’exécution. C'est pourquoi chmod +x myscript
n'est pas requis avant source myscript
Sourcing vous obtenez toutes les variables supplémentaires définies dans le script.
Donc, si vous avez des définitions de configuration ou de fonction, vous devez créer et non exécuter. Les exécutions sont indépendantes de l'environnement des parents.
Si je me souviens bien, l'exécution du script exécute le fichier exécutable dans la ligne #!
avec le fichier de script en tant qu'argument (généralement, en démarrant un nouveau shell et en le localisant dans le nouveau shell, comme avec #!/bin/sh
);
alors que la recherche du script exécute chaque ligne de votre environnement Shell actuel, ce qui est utile pour transformer votre Shell actuel (par exemple, en fournissant un moyen de définir les fonctions du Shell et d'exporter les variables d'environnement).
La commande source
exécute le script fourni (la permission de l'exécutable est non obligatoire ) dans l'environnement current Shell, tandis que ./
exécute le executable script fourni. dans un new Shell.
Vérifiez également cette réponse, par exemple: https://superuser.com/a/894748/432100