J'ai lu ici que le but de export
dans un Shell est de rendre la variable disponible pour les sous-processus démarrés à partir du Shell.
Cependant, j'ai également lu ici et ici que "Les processus héritent de leur environnement de leur parent (le processus qui les a démarrés)."
Si tel est le cas, pourquoi avons-nous besoin de export
? Qu'est-ce que je rate?
Les variables Shell ne font-elles pas partie de l'environnement par défaut? Quelle est la différence?
Votre hypothèse est que les variables Shell sont dans l'environnement. Ceci est une erreur. La commande export
est ce qui définit un nom comme étant dans l'environnement. Donc:
a=1 b=2
export b
résulte dans le courant Shell sachant que $a
se développe en 1 et $b
en 2, mais les sous-processus ne sauront rien de a
parce qu'il n'est pas une partie de l'environnement (même dans le Shell actuel).
Quelques outils utiles:
set
: utile pour visualiser les paramètres actuels du Shell, exportés ou nonset -k
: Définit arguments assignés dans l'environnement. Considérez f() { set -k; env; }; f a=1
set -a
: Indique au shell de mettre n'importe quel nom défini dans l'environnement. Comme mettre export
avant chaque affectation. Utile pour les fichiers .env
, Comme dans set -a; . .env; set +a
.export
: indique au shell de mettre un nom dans l'environnement. L'exportation et l'affectation sont deux opérations entièrement différentes.env
: En tant que commande externe, env
ne peut que vous renseigner sur l'environnement hérité, il est donc utile pour la vérification d'intégrité.env -i
: Utile pour effacer l'environnement avant de démarrer un sous-processus.Alternatives à export
:
name=val command
# Affectation avant que la commande exporte ce nom vers la commande.declare/local -x name
# Exporte le nom, particulièrement utile dans les fonctions Shell lorsque vous voulez éviter d'exposer le nom à une portée extérieure.set -a
# Exporte toutes les affectations suivantes.Il y a une différence entre les variables Shell et les variables d'environnement. Si vous définissez une variable Shell sans export
ing, elle n'est pas ajoutée à l'environnement de processus et n'est donc pas héritée de ses enfants.
En utilisant export
, vous dites au Shell d'ajouter la variable Shell à l'environnement. Vous pouvez tester cela en utilisant printenv
(qui imprime simplement son environnement dans stdout
, car c'est un processus enfant dont vous voyez l'effet des export
ing variables):
#!/bin/sh
MYVAR="my cool variable"
echo "Without export:"
printenv | grep MYVAR
echo "With export:"
export MYVAR
printenv | grep MYVAR
Une variable, une fois exportée, fait partie de l'environnement. PATH
est exporté dans le shell lui-même, tandis que les variables personnalisées peuvent être exportées selon les besoins. En utilisant un code d'installation:
$ cat subshell.sh
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='
Comparer
$ cat test.sh
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh
PATH=/bin
foo=bar
PATH=/bin
foo=bar
Avec
$ cat test2.sh
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh
PATH=/bin
foo=bar
PATH=/bin
Puisque foo
n'est pas exporté par le shell et test2.sh
ne l'a jamais exporté, il ne faisait pas partie de l'environnement de subshell.sh
lors de la dernière exécution.