Quand utiliser un point-virgule entre les variables d'environnement et une commande

14

Quelqu'un peut-il expliquer pourquoi le point-virgule est nécessaire pour que le LANGsoit considéré comme mis à jour par bash?

Ne fonctionne pas:

> LANG=Ja_JP bash -c "echo $LANG"
en_US

Travaux:

> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP

Je travaille avec bash 4.1.10 sous linux et la même version sous cygwin

Richard Corden
la source

Réponses:

23

Les paramètres et autres types d'extensions sont effectués lors de la lecture de la commande, avant son exécution.

La première version,, LANG=Ja_JP bash -c "echo $LANG"est une commande unique. Une fois analysé en tant que tel, $LANGest étendu à en_USavant que quoi que ce soit ne soit exécuté. Une fois le bashtraitement de l'entrée terminé, il accélère un processus, ajoute LANG=Ja_JPà l'environnement comme prévu, puis s'exécute bash -c echo en_US.

Vous pouvez empêcher l'expansion avec des guillemets simples, c'est-à-dire des LANG=Ja_JP bash -c 'echo $LANG'sorties Ja_JP.

Notez que lorsque vous avez une affectation de variable dans le cadre d'une commande, l'affectation affecte uniquement l'environnement de cette commande et non celui de votre shell.

La deuxième version, LANG=Ja_JP; bash -c "echo $LANG"est en fait deux commandes distinctes exécutées en séquence. La première est une simple affectation de variable sans commande, elle affecte donc votre shell actuel.

Ainsi, vos deux extraits sont fondamentalement différents malgré la distinction superficielle d'un seul ;.

Complètement hors sujet, mais pourrais-je recommander d'ajouter un .UTF-8lors du réglage LANG. Il n'y a pas de bonne raison de ne pas utiliser Unicode au 21e siècle.

jw013
la source
Excellente réponse - merci! Concernant l'ajout d'UTF-8. J'essaie de tester la gestion locale d'une application qui doit fonctionner sur plusieurs plateformes dont certaines sont assez anciennes. Entre des différences comme celle-ci (que vous avez heureusement expliquées) et des différences sur linux et cygwin, je suis sur le point de me jeter sous un bus!
Richard Corden
5

VAR=value; somecommand est équivalent à

VAR=value
somecommand

Ce sont des commandes indépendantes exécutées les unes après les autres. La première commande affecte une valeur à la variable shell VAR. Sauf VARs'il s'agit déjà d'une variable d'environnement, elle n'est pas exportée vers l'environnement, elle reste interne au shell. Une déclaration export VARserait exportée VARvers l'environnement.

VAR=value somecommandest une syntaxe différente. L'affectation VAR=valueconcerne l'environnement, mais cette affectation n'est effectuée que dans l'environnement d'exécution de somecommand, et non pour l'exécution ultérieure du shell.

A titre d'exemple:

# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1                        # displays "value"
env | grep '^VAR1='               # displays nothing
VAR2=value env | grep '^VAR2='    # displays "VAR2=value"
echo $VAR2                        # displays nothing
Gilles 'SO- arrête d'être méchant'
la source
Je n'avais pas vraiment pensé à la différence entre une variable shell vs une variable d'environnement. Je vais devoir faire des recherches. Merci d'avoir répondu.
Richard Corden