Si je cours
export TEST=foo
echo $TEST
Il produit foo.
Si je cours
TEST=foo echo $TEST
Ce ne est pas. Comment puis-je obtenir cette fonctionnalité sans utiliser export ou un script?
Si je cours
export TEST=foo
echo $TEST
Il produit foo.
Si je cours
TEST=foo echo $TEST
Ce ne est pas. Comment puis-je obtenir cette fonctionnalité sans utiliser export ou un script?
Réponses:
Cela est dû au fait que le shell développe la variable dans la ligne de commande avant d' exécuter la commande et que la variable n'existe pas à ce moment-là. Si tu utilises
TEST=foo; echo $TEST
ça va marcher.
export
fera apparaître la variable dans l'environnement des commandes exécutées ultérieurement (pour savoir comment cela fonctionne à bash, voir help export
). Si vous avez seulement besoin que la variable apparaisse dans l'environnement d'une commande, utilisez ce que vous avez essayé, à savoir:
TEST=foo your-application
$TEST
avant que la ligne de commande ne soit exécutée. Une fois que l ' echo
est en cours d' exécution (notez également que echo
cela se traduira généralement par la commande intégrée du shell et non par /bin/echo
), il voit la variable définie dans son environnement. Cependant, echo $TEST
ne dit pas echo
de sortir le contenu de la variable TEST
depuis son environnement. Il demande au shell de fonctionner echo
avec l'argument comme étant tout ce qui se trouve actuellement dans la variable appelée TEST
- et ce sont deux choses très différentes.
var=value sh -c 'echo "$var"'
?
"… $var …"
) mais pas entre guillemets simples (par exemple, '… $var …'
). Étant donné qu'il echo "$var"
s'agit de guillemets simples, cette chaîne entière est transmise au sh -c
shell new ( ) sans être interprétée par le shell externe et interactif. … (Suite)
sh -c
shell enfant new ( ).
Je soupçonne que vous voulez que les variables shell aient une portée limitée, plutôt que les variables d'environnement. Les variables d'environnement sont une liste de chaînes passées aux commandes lorsqu'elles sont exécutées .
Dans
var=value echo whatever
Vous transmettez la var=value
chaîne à l'environnement que l'écho reçoit. Cependant, echo
ne fait rien avec sa liste d'environnement et de toute façon, dans la plupart des shells, echo
est construit et n'est donc pas exécuté .
Si tu avais écrit
var=value sh -c 'echo "$var"'
Cela aurait été une autre affaire. Ici, nous passons var=value
à la sh
commande et sh
utilisons son environnement. Coquilles convertissent chacune des variables qu'ils reçoivent de leur environnement à une variable shell, de sorte que la var
variable d'environnement sh
reçoit sera converti en une $var
variable et quand il se dilate dans cette echo
ligne de commande, qui deviendront echo value
. Parce que l'environnement est par défaut hérité, echo
recevra également var=value
dans son environnement (ou le serait s'il était exécuté), mais encore une fois, echo
ne se soucie pas de l'environnement.
Maintenant, si comme je le soupçonne, ce que vous voulez, c'est limiter la portée des variables du shell, plusieurs approches sont possibles.
Portable (Bourne et POSIX):
(var=value; echo "1: $var"); echo "2: $var"
Le (...) ci-dessus démarre un sous-shell (un nouveau processus shell dans la plupart des shells), ainsi toute variable y déclarée n'affectera que ce sous-shell, aussi je m'attendrais à ce que le code ci-dessus génère "1: valeur" et "2:" ou "2: quel que soit ce que var a été configuré avant".
Avec la plupart des shells de type Bourne, vous pouvez utiliser des fonctions et la fonction "locale":
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
Avec zsh, vous pouvez utiliser des fonctions inline:
(){ local var=value; echo "1: $var"; }; echo "2: $var"
ou:
function { local var=value; echo "1: $var"; }; echo "2: $var"
Avec bash et zsh (mais pas ash, pdksh ou AT & T ksh), cette astuce fonctionne aussi:
var=value eval 'echo "1: $var"'; echo "2: $var"
Une variante qui fonctionne en quelques coquilles (plus dash
, mksh
, yash
) mais pas zsh
(sauf dans sh
/ ksh
émulation):
var=value command eval 'echo "1: $var"'; echo "2: $var"
(utiliser command
devant un shell spécial (ici eval
) dans les shells POSIX supprime leur particularité (ici, les affectations de variables d'entre eux restent en vigueur après leur retour))
Vous le faites correctement, mais la syntaxe bash est facile à interpréter de manière erronée: vous pouvez penser que cela echo $TEST
provoque echo
de récupérer TEST
env var puis de l’imprimer, ce n’est pas le cas. Donc donné
export TEST=123
ensuite
TEST=456 echo $TEST
implique la séquence suivante:
Le shell analyse toute la ligne de commande et exécute toutes les substitutions de variables. La ligne de commande devient alors
TEST=456 echo 123
Il crée les vars temporaires définis avant la commande. Il enregistre la valeur actuelle de TEST
et la remplace par 456; la ligne de commande est maintenant
echo 123
Il exécute la commande restante, qui dans ce cas affiche 123 sur stdout (la commande shell restante n’a même pas utilisé la valeur temp de TEST
)
Il restaure la valeur de TEST
Utilisez plutôt printenv, car cela n'implique pas de substitution de variable:
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
printenv
utile de tester / prouver le concept (se comporte comme un script, par opposition à echo
)
Vous pouvez obtenir ce travail en utilisant:
TEST=foo && echo $TEST
TEST=foo
s'exécute en tant qu'instruction distincte - elle n'est pas simplement définie dans le contexte de echo
.