Différence entre les variables shell exportées et celles qui ne sont pas dans bash

41

Bash semble faire la différence entre les variables exportées et les autres.

Exemple:

$ FOO=BAR
$ env | grep FOO
$ set | grep FOO
FOO=BAR

setvoit la variable mais envne le fait pas.

$ export BAR=FOO
$ env | grep FOO
BAR=FOO
$ set | grep FOO
BAR=FOO
FOO=BAR

setvoit les deux variables mais envne voit que la variable exportée.

Je sais que setc'est une bash intégré et envn'est pas.

Quelles sont les différences entre les variables exportées et celles qui ne le sont pas?

lesmana
la source
17
Note terminologique: une «variable d'environnement» est toujours exportée. Une variable non exportée est une "variable shell" (ou "paramètre").
Gilles 'SO- arrête d'être méchant' le

Réponses:

44

Les variables exportées sont transférées dans l'environnement des commandes exécutées par le shell qui les a exportées, tandis que les variables non exportées sont locales à l'appel du shell en cours. De la exportpage de manuel:

L'enveloppe doit attribuer l'attribut d'exportation aux variables correspondant aux noms spécifiés, ce qui les place dans l'environnement des commandes exécutées ultérieurement.

setgénère l'environnement actuel, qui inclut toutes les variables locales non exportées. envest utilisé pour lancer des programmes dans un nouvel environnement et, sans aucun argument, affichera ce que serait ce nouvel environnement. Comme il envcrée un nouvel environnement, seules les variables exportées sont importées, comme c'est le cas pour tout programme lancé à partir de ce shell. Par exemple, la création d'un deuxième shell dans le premier (je $$représentais autrefois les invites dans la coque interne):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Notez que c'est la variable qui est exportée, pas seulement sa valeur. Cela signifie qu'une fois que vous export FOO, FOOdevient une variable globale et apparaît dans des environnements suivants, même si plus tard changé:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
Michael Mrozek
la source
Donc, si vous êtes uniquement préoccupé par le shell actuel, avez-vous besoin d'exporter? Séparément, pourquoi localele shell actuel n’afficherait-il pas les mises à jour?
Pacerier