GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle est la différence entre exécuter un script Bash et le sourcer ?

Approvisionnement un script exécutera les commandes dans le courant processus shell.

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

Utilisez source si vous souhaitez que le script modifie l'environnement dans votre shell en cours d'exécution. utilisez exécuter sinon.

"l'environnement" sont des choses comme le répertoire de travail actuel et les variables d'environnement. également les paramètres du shell (entre autres fonctionnalités d'historique et d'achèvement). il y en a plus mais ce sont les plus visibles.

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

Terminologie

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

./myscript

Cela va s'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 car le répertoire courant n'est généralement pas (et ne devrait généralement pas être) dans $PATH .

myscript

Cela va s'exécuter myscript si le fichier est exécutable et situé dans un répertoire en $PATH .

source myscript

Cela va sourcer myscript . Le fichier n'a pas besoin d'ê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 en $PATH .

. myscript

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

et pour être complet :

exec myscript

Cela mettra fin au shell actuel, puis exécutera monscript à la place du shell terminé. Cela signifie que lorsque mon script est terminé, il n'y a plus d'ancien shell vers lequel revenir. exec est puissant mais rarement nécessaire.

Je mets quelques liens à la fin pour plus d'informations sur ces sujets.

Démonstration

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 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 personnel.

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éfini 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 par la suite montre que la variable n'est pas définie et que le répertoire n'a pas changé. Qu'est-il arrivé? Les modifications ont été apportées dans un nouveau coquille. Le courant shell a généré un nouveau shell pour exécuter le script. Le script s'exécute 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 achetons 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 apportées à 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 celle de la source 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 $$ développe le PID du processus shell en cours d'exécution)

Imprimez d'abord le PID du shell actuel :

$ echo $$
25009

Source du script :

$ source pid.sh
25009

Exécutez le script, notez le PID :

$ ./pid.sh
25011

Source à nouveau :

$ source pid.sh
25009

Exécutez à nouveau :

$ ./pid.sh
25013

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

Résumé

La recherche et l'exécution du script exécuteront les commandes du script ligne par ligne, comme si vous tapiez ces commandes à la main ligne par ligne.

Les différences sont :

  • Lorsque vous exécutez le script que vous ouvrez un nouveau shell, tapez les commandes dans le nouveau shell, copiez la sortie dans 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 dans lequel vous tapez les commandes dans votre courant coquille. Toute modification de l'environnement prendra effet et restera dans votre shell actuel.

Utilisez source si vous souhaitez que le script modifie l'environnement dans votre shell en cours d'exécution. utilisez exécuter sinon.

Voir aussi :

  • https://stackoverflow.com/questions/6331075/why-do-you-need-dot-slash-before-script-name-to-run-it-in-bash
  • https://askubuntu.com/questions/182012/is-there-a-difference-between-and-source-in-bash-after-all
  • https://stackoverflow.com/questions/18351198/what-are-the-uses-of-the-exec-command-in-shell-scripts

L'exécution d'un script l'exécute dans un processus enfant séparé, c'est-à-dire qu'une instance distincte de shell est invoquée pour traiter le script. Cela signifie que toutes les variables d'environnement, etc., définies dans le script ne peuvent pas être mis à jour dans le shell parent (actuel).

Sourcer un script signifie qu'il est analysé et exécuté par le shell actuel lui-même. C'est comme si vous tapiez le contenu du script. Pour cette raison, le script source 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 de position dans le shell actuel, ils sont inchangés.

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

echo a $*

et je fais :

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

J'obtiens quelque chose comme :

a Fri Dec 11 07:34:17 PST 2009

Attendu que :

$ set `date`
$ ./a.sh

me donne :

a

J'espère que ça aide.


le sourcing revient essentiellement à taper chaque ligne du script à l'invite de commande une à la fois...

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 renvoie.


Linux
  1. La différence entre l'approvisionnement ('.' ou 'source') et l'exécution d'un fichier dans Bash ?

  2. La différence entre les opérateurs bash [[ Vs [ Vs ( Vs ((?

  3. Quelle est la différence entre #!/usr/bin/env bash et #!/usr/bin/bash ?

  4. Quelle est la différence entre fsck et e2fsck ?

  5. Quelle est la différence entre `su -` et `su --login` ?

Quelle est la différence entre Linux et Unix ?

Quelle est la différence entre la connexion et le shell sans connexion

Qu'est-ce qu'un Hyperviseur ? Quelle est la différence entre les types 1 et 2 ?

Quelle est la différence entre curl et Wget ?

Différence entre les commandes dans le script bash et les commandes dans le terminal

quelle est la différence entre remonter et démonter/monter ?