Définition d'une variable avec ou sans export
à quoi sert export
?
Quelle est la différence entre:
export name=value
et
name=value
14 réponses
export
rend la variable disponible pour les sous-processus.
C'est-à-dire,
export name=value
signifie que le nom de la variable est disponible pour tout processus vous exécutez à partir de ce processus shell. Si vous voulez qu'un processus utilise cette variable, utilisez export
, et exécutez le processus à partir de ce shell.
name=value
signifie que la portée variable est limitée au réservoir et qu'elle n'est pas disponible pour: tout autre processus. Vous utiliseriez ceci pour (disons) des variables de boucle, des variables temporaires, etc.
il est important de noter que l'exportation d'une variable ne la rend pas disponible pour les processus parent. Autrement dit, spécifier et exporter une variable dans un processus généré ne la rend pas disponible dans le processus qui l'a lancé.
pour illustrer ce que disent les autres réponses:
$ foo="Hello, World"
$ echo $foo
Hello, World
$ bar="Goodbye"
$ export foo
$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar
bash-3.2$
D'autres ont répondu que l'exportation met la variable à la disposition des sous-cellules, et c'est correct mais seulement un effet secondaire. Lorsque vous exportez une variable, il met cette variable dans l'environnement du shell courant (c'est à dire le shell appels putenv(3) ou setenv(3)). L'environnement d'un processus est hérité de l'ensemble d'exec, ce qui rend la variable visible dans les sous-couches.
Éditer (avec 5 ans de point de vue): c'est une réponse idiote. Le but de "l'exportation" est de rendre les variables "être dans l'environnement de par la suite exécuté les commandes", que ces commandes soient sous-coquille ou sous-processus. Une implémentation naïve serait de simplement mettre la variable dans l'environnement du shell, mais cela rendrait impossible l'implémentation de export -p
.
il a été dit qu'il n'est pas nécessaire d'exporter à bash lors de la fraye des sous-coquilles, alors que d'autres ont dit exactement le contraire. Il est important de noter la différence entre les subshells (ceux qui sont créés par ()
, ``
, $()
ou loops) et les sous-processus (processus qui sont invoqués par leur nom, par exemple un bash
littéral apparaissant dans votre script). Sous-coquille sera ont accès à toutes les variables de la mère, indépendamment de leur exportés en l'état. Les sous-processus d'autre part seront seulement voir les variables exportées. Ce qui est commun dans ces deux constructions est que ni l'un ni l'autre ne peut transmettre les variables à l'interpréteur de commandes parent.
$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:
il y a une autre source de confusion: certains pensent que les sous-processus "fourchés" sont ceux qui ne voient pas les variables non exportées. Habituellement fork () s est immédiatement suivi par exec () s, et c'est pourquoi il semblerait que la fork() soit chose à trouver, alors qu'en fait c'est le exec(). Vous pouvez exécuter des commandes sans fork()ing en premier avec la commande exec
, et les processus lancés par cette méthode n'auront pas non plus accès à des variables inexportées:
$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export
notez que nous ne voyons pas la ligne parent:
cette fois, parce que nous avons remplacé le shell parent par la commande exec
, donc il ne reste plus rien pour exécuter cette commande.
export NAME=value
pour les paramètres et les variables qui ont un sens pour un sous-processus.
NAME=value
temporaires ou les variables de boucle privé dans le shell en cours de processus.
plus précisément, export
marque le nom de la variable dans l'environnement qui copie à un sous-processus et leurs sous-processus lors de la création. Aucun nom ni aucune valeur n'est recopié du sous-processus.
-
Un erreur courante consiste à placer un espace autour du signe égal:
$ export FOO = "bar" bash: export: `=': not a valid identifier
-
seule la variable exportée (
B
) est vue par le sous-processus:$ A="Alice"; export B="Bob"; echo "echo A is $A. B is $B" | bash A is . B is Bob
-
les changements dans le sous-processus ne changent pas le shell principal:
$ export B="Bob"; echo 'B="Banana"' | bash; echo $B Bob
-
les Variables marquées pour l'exportation ont des valeurs copiées lorsque le sous-processus est créé:
$ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash & [1] 3306 $ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash Subprocess 1 has B=Bob Subprocess 2 has B=Banana [1]+ Done echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
-
seules les variables exportées font partie de l'environnement (
man environ
):$ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB" BOB=Bob
ainsi, maintenant il devrait être aussi clair que le soleil de l'été! Merci à Brain Agnew, alexp, et William Prusell.
export
mettra la variable à disposition de tous les shells fourchés à partir du shell actuel.
il est à noter que vous pouvez exporter une variable et plus tard changer la valeur. La valeur changée de la variable sera disponible pour les processus enfants. Une fois que export a été défini pour une variable, vous devez faire export -n <var>
pour supprimer la propriété.
$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
comme vous le savez peut-être déjà, UNIX permet aux processus D'avoir un ensemble de variables d'environnement, qui sont des couples clé/valeur, la clé et la valeur étant des chaînes. Le système d'exploitation est responsable de garder ces paires pour chaque processus séparément.
programme peut accéder à ses variables d'environnement à travers cette API UNIX:
-
char *getenv(const char *name);
-
int setenv(const char *name, const char *value, int override);
-
int unsetenv(const char *name);
" les processus héritent aussi des variables d'environnement des processus parents. Le système d'exploitation est responsable de la création d'une copie de tous les "envars" au moment où le processus enfant est créé.
Bash , entre autres shells, est capable de régler ses variables d'environnement sur demande de l'utilisateur. C'est pour cela que export
existe.
export
est une commande de Bash pour définir une variable d'environnement pour Bash. Tout les variables définies avec cette commande seraient héritées par tous les processus que cette Bash créerait.
Plus sur Environnement Bash
un autre type de variable dans Bash est la variable interne. Comme Bash n'est pas seulement un interpréteur de commandes interactif, C'est en fait un interpréteur de script, comme tout autre interpréteur (par exemple Python), il est capable de conserver son propre ensemble de variables. Il est à noter que Bash (contrairement à Python) supporte seulement variables de chaîne de caractères.
la Notation pour définir les variables de Bash est name=value
. Ces variables restent à L'intérieur de Bash et n'ont rien à voir avec les variables d'environnement conservées par le système d'exploitation.
plus sur paramètres Shell (y compris les variables)
vaut également la peine de noter que, selon Bash manuel de référence:
l'environnement de toute commande ou fonction simple peut être augmentée temporairement en le préfixant avec les assignations de paramètres, comme décrit dans Shell " Paramètres . Ces énoncés de cession ne concernent que les environnement vu par ce commandement.
pour résumer:
-
export
est utilisé pour définir la variable d'environnement dans le système d'exploitation. Cette variable sera disponible pour tous les processus enfants créés par Bash courant processus jamais après. - Bash variable notation (nom=valeur) est utilisé pour définir des variables locales disponibles uniquement pour les processus actuel de bash
- Bash variable notation préfixer une autre commande crée une variable d'environnement uniquement pour la portée de cette commande.
la réponse acceptée implique ceci, mais je voudrais rendre explicite la connexion aux constructions shell:
comme déjà mentionné, export
mettra une variable à la disposition de la coquille et des enfants. Si export
est et non utilisé, la variable ne sera disponible que dans le shell, et seul le shell builtins peut y accéder.
C'est-à-dire,
tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Voici encore un autre exemple:
VARTEST="value of VARTEST"
#export VARTEST="value of VARTEST"
sudo env | grep -i vartest
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'
Uniquement à l'aide de l'exportation VARTEST la valeur de VARTEST est disponible en sudo bash -c"...'!
pour d'autres exemples, voir:
-
bash-hackers.org/wiki/doku.php/scripting/processtree
Juste pour montrer la différence entre un produit exporté variable dans l'environnement (env) et un non exportée variable n'étant pas dans l'environnement:
si je fais cela:
$ MYNAME=Fred
$ export OURNAME=Jim
alors seulement $OURNAME apparaît dans l'env. La variable $MYNAME n'est pas dans l'env.
$ env | grep NAME
OURNAME=Jim
mais la variable $MYNAME existe dans le shell
$ echo $MYNAME
Fred
deux des créateurs D'UNIX, Brian Kernighan et Rob Pike, expliquent cela dans leur livre "The UNIX Programming Environment". Google pour le titre et vous trouverez facilement une version pdf.
ils traitent des variables shell dans la section 3.6, et se concentrent sur l'utilisation de la commande export
à la fin de cette section:
lorsque vous voulez rendre la valeur d'une variable accessible dans les sous-shells, la commande d'exportation du shell doit être utiliser. (Vous pourriez penser à la raison pour laquelle il n'y a aucun moyen d'exporter la valeur d'une variable d'un sous-shell à son parent).
bien qu'il ne soit pas explicitement mentionné dans la discussion, il n'est pas nécessaire d'utiliser l'exportation lorsque la fraye d'un sous-sol à partir de l'intérieur de bash puisque toutes les variables sont copiées dans le processus enfant.
par défaut, les variables créées dans un script ne sont disponibles que pour le shell courant; les processus enfants (sous-shells) n'auront pas accès aux valeurs qui ont été définies ou modifiées. Pour permettre aux processus enfants de voir les valeurs, il faut utiliser la commande export.