Réponse courte
Dans votre question, la deuxième commande n'utilise ni la fonction .
Shell ni l'option source
builtin. Au lieu de cela, vous êtes en fait exécuter le script dans un Shell séparé, en l'invoquant par son nom comme vous le feriez avec tout autre fichier exécutable. Cela lui donne un ensemble séparé de variables (bien que si vous exporter une variable dans son Shell parent, elle sera une variable d'environnement pour tout processus enfant et donc sera inclus dans les variables d'un Shell enfant ). Si vous modifiez le /
à un espace, alors cela l'exécuterait avec le .
intégré, ce qui est équivalent à source
.
Explication étendue
Il s'agit de la syntaxe du source
Shell intégré, qui exécute le contenu d'un Shell dans la Shell courante (et donc avec les variables de la Shell courante) :
source testenv.sh
Il s'agit de la syntaxe du .
intégré, qui fait la même chose que source
:
. testenv.sh
Cependant, cette syntaxe exécute le script comme un fichier exécutable, lançant un nouveau script pour l'exécuter :
./testenv.sh
Ce n'est pas utiliser le .
intégré. Plutôt, .
fait partie du chemin d'accès au fichier que vous exécutez. D'une manière générale, vous pouvez exécuter n'importe quel fichier exécutable dans un Shell en l'invoquant avec un nom qui contient au moins un /
caractère. Pour exécuter un fichier dans le répertoire courant, le faire précéder de ./
est donc le moyen le plus simple. A moins que le répertoire courant ne soit dans votre PATH
vous ne pouvez pas exécuter le script avec la commande testenv.sh
. Cela permet d'éviter que des personnes n'exécutent accidentellement des fichiers dans le répertoire courant alors qu'elles ont l'intention d'exécuter une commande système ou un autre fichier qui existe dans un répertoire répertorié dans le fichier de configuration de l'ordinateur. PATH
variable d'environnement.
Étant donné que l'exécution d'un fichier par son nom (plutôt qu'à l'aide de la commande source
ou .
) l'exécute dans un nouveau Shell, il aura son propre ensemble de variables Shell. La nouvelle Shell hérite les variables d'environnement du processus appelant (qui dans ce cas est votre Shell interactif) et ces variables d'environnement deviennent effectivement des variables Shell dans le nouveau Shell. Cependant, pour qu'une variable Shell soit transmise à la nouvelle Shell, l'une des conditions suivantes doit être remplie :
-
La variable Shell a été exportée, ce qui en fait une variable d'environnement. Utilisez la variable export
Shell intégré pour cela. Dans votre exemple, vous pouvez utiliser export MY_VAR=12345
pour définir et exporter la variable en une seule étape, ou si elle est déjà définie, vous pouvez simplement utiliser la fonction export MY_VAR
.
-
La variable Shell est explicitement définie et passée pour la commande que vous exécutez, ce qui en fait une variable d'environnement pour la durée de la commande exécutée. Cette généralement accomplit cela :
MY_VAR=12345 ./testenv.sh
Si MY_VAR
est une variable Shell qui n'a pas été exportée, vous pouvez même exécuter testenv.sh
con MY_VAR
passé comme variable d'environnement par le fixer sur lui-même :
MY_VAR="$MY_VAR" ./testenv.sh
./
La syntaxe pour scripts nécessite une ligne de hashbang pour fonctionner (correctement)
Au fait, veuillez noter que, lorsque vous invoquez un exécutable par son nom comme ci-dessus (et non pas avec l'attribut .
ou source
Shell built-ins), quel programme Shell est utilisé pour l'exécuter est no généralement déterminé par le Shell à partir duquel vous l'exécutez. Au lieu de cela :
-
Pour les fichiers binaires, le noyau peut être configuré pour exécuter des fichiers de ce type particulier. Il examine les deux premiers octets du fichier à la recherche d'un "numéro magique" qui indique de quel type d'exécutable binaire il s'agit. C'est ainsi que les binaires exécutables sont capables de fonctionner.
C'est, bien sûr, extrêmement important, car un script ne peut pas fonctionner sans un script ou autre interprète, qui est un binaire exécutable ! De plus, de nombreuses commandes et applications sont des binaires compilés plutôt que des script.
( #!
est la représentation textuelle du "chiffre magique" indiquant un exécutable textuel).
-
Pour les fichiers qui sont censés être exécutés dans un Shell ou un autre langage interprété, la première ligne ressemble à ceci :
#!/bin/sh
/bin/sh
peut être remplacé par tout autre Shell ou interpréteur destiné à exécuter le programme. Par exemple, un programme Python peut commencer par la ligne :
#!/usr/bin/python
Ces lignes sont appelées hashbang, shebang, et un certain nombre d'autres noms similaires. Voir ce qui suit Entrée du FOLDOC ce Article de Wikipedia y Est-ce que #!/bin/sh est lu par l'interpréteur ? pour plus d'informations.
-
Si un fichier texte est exécutable marqué et vous l'exécutez depuis votre Shell (comme ./filename
) mais ce n'est pas le cas commencer par #!
le noyau ne l'exécute pas. Cependant, voyant que cela s'est produit, votre Shell sera essayez pour l'exécuter en passant son nom à algunos Shell. Il existe peu d'exigences placé sur ce que Shell qui est ( "Le Shell doit exécuter une commande équivalente à l'invocation d'un Shell..." ). En pratique certains coquillages, y compris bash
* --exécutent une autre instance d'eux-mêmes, tandis que d'autres utilisent /bin/sh
. Je vous recommande vivement d'éviter cela et d'utiliser une ligne hashbang à la place (ou d'exécuter le script en le passant à l'interpréteur souhaité, par ex, bash filename
).
* <a href="https://www.gnu.org/software/bash/manual/" rel="noreferrer">Manuel de GNU Bash </a>, <a href="https://www.gnu.org/software/bash/manual/bash.html#Command-Search-and-Execution" rel="noreferrer">3.7.2 Recherche et exécution de commandes </a>: " Si cette exécution échoue parce que le fichier n'est pas au format exécutable, et que le fichier n'est pas un répertoire, il est supposé être une <em>Shell Shell </em>et le Shell l'exécute comme décrit dans <a href="https://www.gnu.org/software/bash/manual/bash.html#Shell-Scripts" rel="noreferrer">Shell Shell </a>."