Quelle est la différence entre set, export et env et quand dois-je utiliser chacun?

92

De temps en temps, je bouscule un script bash et il me semble qu'il existe plusieurs manières de définir une variable:

key=value
env key=value
export key=value

Lorsque vous êtes dans un script ou une commande unique (par exemple, je chaîne souvent une variable avec un lanceur Wine pour définir le bon préfixe Wine), ils semblent être complètement interchangeables mais cela ne peut certainement pas être le cas. cas.

Quelle est la différence entre ces trois méthodes et pouvez-vous me donner un exemple de quand je voudrais spécifiquement utiliser chacune d’elles?

Certainement lié à Quelle est la différence entre 'VAR = ...' et 'export VAR = ...'? mais je veux savoir comment env s'intègre aussi à cela, et certains exemples montrant les avantages de chacun seraient également intéressants:)

    
posée Oli 24.10.2012 - 11:34
la source

1 réponse

91

Considérons un exemple spécifique. La commande grep utilise une variable d'environnement appelée GREP_OPTIONS pour définir les options par défaut.

Maintenant. Étant donné que le fichier test.txt contient les lignes suivantes:

line one
line two

exécuter la commande grep one test.txt retournera

line one

Si vous exécutez grep avec l’option -v , les lignes qui ne correspondent pas seront renvoyées, la sortie sera donc

line two

Nous allons maintenant essayer de définir l’option avec une variable d’environnement.

  1. Les variables d'environnement définies sans export ne seront pas héritées dans l'environnement des commandes que vous appelez.

    GREP_OPTIONS='-v'
    grep one test.txt
    

    Le résultat:

    line one
    

    Évidemment, l'option -v n'a pas été transmise à grep .

    Vous souhaitez utiliser ce formulaire lorsque vous définissez une variable uniquement pour le shell à utiliser, par exemple dans for i in * ; do , vous ne souhaitez pas exporter $i .

  2. Cependant, la variable est transmise à l’environnement de cette ligne de commande particulière, vous pouvez donc le faire

    GREP_OPTIONS='-v' grep one test.txt
    

    qui retournera le prévu

    line two
    

    Vous utilisez ce formulaire pour modifier temporairement l’environnement de cette instance particulière du programme lancé.

  3. L'exportation d'une variable entraîne l'héritage de la variable:

    export GREP_OPTIONS='-v'
    grep one test.txt
    

    retourne maintenant

    line two
    

    Il s’agit de la méthode la plus courante de définition de variables pour l’utilisation des processus lancés ultérieurement dans un shell

  4. Tout cela a été fait en bash. export est un bash builtin; VAR=whatever est la syntaxe bash. env , d'autre part, est un programme en soi. Lorsque env est appelé, les événements suivants se produisent:

    1. La commande env est exécutée en tant que nouveau processus
    2. env modifie l'environnement et
    3. appelle la commande fournie en argument. Le processus env est remplacé par le processus command .

    Exemple:

    env GREP_OPTIONS='-v' grep one test.txt
    

    Cette commande lancera deux nouveaux processus: (i) env et (ii) grep (en réalité, le second processus remplacera le premier). Du point de vue du processus grep , le résultat est exactement identique à l'exécution

    GREP_OPTIONS='-v' grep one test.txt
    

    Cependant, vous pouvez utiliser cet idiome si vous êtes en dehors de bash ou ne souhaitez pas lancer un autre shell (par exemple, lorsque vous utilisez la famille de fonctions exec() plutôt que l'appel system() ).

Remarque supplémentaire sur #!/usr/bin/env

C'est aussi pourquoi l'idiome #!/usr/bin/env interpreter est utilisé plutôt que #!/usr/bin/interpreter . env ne nécessite pas de chemin complet vers un programme, car il utilise la fonction execvp() qui recherche dans la variable PATH comme le fait un shell, puis remplace lui-même par la commande exécutée . Ainsi, il peut être utilisé pour savoir où un interpréteur (comme perl ou python) "se trouve" sur le chemin.

Cela signifie également qu'en modifiant le chemin actuel, vous pouvez influencer la variante python qui sera appelée. Cela rend les suivants possibles:

echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
calibre

au lieu de lancer Calibre, il en résultera

I am an evil interpreter!
    
réponse donnée January 24.10.2012 - 12:21
la source

Lire d'autres questions sur les étiquettes