Question Définir une variable avec ou sans export


Quel est export pour?

Quelle est la différence entre:

export name=value

et

name=value

685
2017-07-21 09:09


origine


Réponses:


export rend la variable disponible pour les sous-processus.

C'est,

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 exportet exécutez le processus à partir de ce shell.

name=value

signifie que la portée de la variable est restreinte au shell et n'est disponible pour aucun 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 parents. Autrement dit, la spécification et l'exportation d'une variable dans un processus engendré ne la rendent pas disponible dans le processus qui l'a lancée.


771
2017-07-21 09:45



Pour illustrer ce que les autres réponses disent:

$ 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$ 

193
2017-07-21 09:56



D'autres ont répondu que l'exportation rend la variable disponible pour les sous-couches, et c'est correct mais seulement un effet secondaire. Lorsque vous exportez une variable, elle place cette variable dans l'environnement du shell actuel (c'est-à-dire que le shell appelle putenv (3) ou setenv (3)). L'environnement d'un processus est hérité à travers exec, ce qui rend la variable visible dans les sous-cases.

Edit (avec 5 ans de perspective): c'est une réponse idiote. Le but de 'export' est de faire en sorte que les variables "soient dans l'environnement des commandes exécutées par la suite", que ces commandes soient des sous-couches ou des sous-processus. Une implémentation naïve consisterait à simplement mettre la variable dans l'environnement du shell, mais cela rendrait impossible la mise en œuvre export -p.


63
2017-07-21 10:33



Il a été dit qu'il n'est pas nécessaire d'exporter en bash lors de la reproduction des sous-couches, alors que d'autres ont dit exactement le contraire. Il est important de noter la différence entre les sous-couches (celles qui sont créées par (), ``, $() ou boucles) et sous-processus (processus qui sont appelés par leur nom, par exemple un littéral bash apparaissant dans votre script). Subshells volonté avoir accès à toutes les variables du parent, quel que soit leur état exporté. D'autre part, les sous-processus seulement voir les variables exportées. Ce qui est commun dans ces deux constructions est qu'elles ne peuvent pas non plus retransmettre des variables au shell 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 existe une autre source de confusion: certains pensent que les sous-processus «fourchus» sont ceux qui ne voient pas les variables non exportées. Habituellement fork () s est immédiatement suivi de exec () s, et c'est pourquoi il semblerait que fork () soit la chose à rechercher, alors qu'en fait c'est exec (). Vous pouvez exécuter des commandes sans fork () en premier avec le exec command, et les processus démarrés par cette méthode n'auront pas non plus accès aux variables non exporté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 le parent: ligne cette fois, parce que nous avons remplacé le shell parent avec le exec commande, il n'y a plus rien pour exécuter cette commande.


43
2018-02-12 08:16



export NAME=value pour les paramètres et les variables qui ont un sens pour un sous-processus.

NAME=value pour les variables temporaires ou de boucle privées au processus shell actuel.

Plus en détail, export marque le nom de la variable dans l'environnement qui copie vers un sous-processus et ses sous-processus lors de la création. Aucun nom ou valeur n'est jamais copié du sous-processus.

  • Une 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 vu par le sous-processus:

    $ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
    A is . B is Bob
    
  • Les modifications du sous-processus ne modifient 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 lors de la création du sous-processus:

    $ 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 deviennent partie intégrante de l'environnement (man environ):

     $ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
     BOB=Bob
    

Donc, maintenant il devrait être aussi clair que le soleil de l'été! Merci à Brain Agnew, alexp et William Prusell.


26
2018-04-24 17:10



Il convient de noter que vous pouvez exporter une variable et modifier ultérieurement la valeur. La valeur modifiée de la variable sera disponible pour les processus enfants. Une fois que l'exportation a été définie pour une variable, vous devez export -n <var> pour enlever la propriété.

$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset

9
2018-02-10 16:36



export rendra la variable disponible pour tous les shells issus du shell actuel.


8
2017-07-21 09:10



Comme vous le savez peut-être, UNIX permet aux processus d'avoir un ensemble de variables d'environnement, qui sont des paires clé / valeur, les clés et les valeurs étant des chaînes. Le système d'exploitation est responsable de garder ces paires pour chaque processus séparément.

Le programme peut accéder à ses variables d'environnement via 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 également 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éé.

Frapper, entre autres shells, est capable de définir ses variables d'environnement à la demande de l'utilisateur. C'est quoi export existe pour.

export est une commande Bash pour définir la variable d'environnement pour Bash. Toutes les variables définies avec cette commande seraient héritées par tous les processus que ce Bash créerait.

Plus sur Environnement à Bash

Un autre type de variable dans Bash est une variable interne. Puisque Bash n'est pas seulement un shell interactif, c'est en fait un interpréteur de script, comme tout autre interpréteur (par exemple Python) il est capable de garder son propre ensemble de variables. Il convient de mentionner que Bash (contrairement à Python) ne supporte que les variables de chaîne.

La notation pour définir les variables Bash est name=value. Ces variables restent dans 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)

A noter également que, selon le manuel de référence Bash:

L'environnement pour toute commande ou fonction simple peut être augmenté   temporairement en le préfixant avec des affectations de paramètres, comme décrit   dans Paramètres Shell. Ces déclarations d'affectation concernent uniquement   environnement vu par cette commande.


Pour résumer les choses:

  • 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 le processus Bash actuel.
  • La notation de variable Bash (name = value) est utilisée pour définir les variables locales disponibles uniquement pour le processus courant de bash
  • La notation de variable Bash préfixant une autre commande crée une variable d'environnement uniquement pour la portée de cette commande.

5
2018-06-19 16:48



le réponse acceptée Cela implique ceci, mais je voudrais expliciter la connexion avec les builtins shell:

Comme déjà mentionné, export mettra une variable à la disposition du shell et des enfants. Si export est ne pas utilisée, la variable ne sera disponible que dans le shell, et seulement shell builtins peut y accéder.

C'est,

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

5
2017-09-22 07:33



Voici 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}"'  

Seulement en utilisant l'export VARTEST la valeur de VARTEST est disponible dans sudo bash -c '...'!

Pour d'autres exemples, voir:


3
2017-07-22 07:06



Juste pour montrer la différence entre une variable exportée étant dans l'environnement (env) et une variable non-exportée n'étant pas dans l'environnement:

Si je fais ceci:

$ MYNAME=Fred
$ export OURNAME=Jim

alors seulement $ OURNAME apparaît dans l'env. La variable $ MYNAME n'est pas dans l'environnement env.

$ env | grep NAME
OURNAME=Jim

mais la variable $ MYNAME existe dans le shell

$ echo $MYNAME
Fred

2
2018-02-05 11:00