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.
exportfera 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
$TESTavant que la ligne de commande ne soit exécutée. Une fois que l ' echoest en cours d' exécution (notez également que echocela 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 $TESTne dit pas echode sortir le contenu de la variable TESTdepuis son environnement. Il demande au shell de fonctionner echoavec 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 -cshell new ( ) sans être interprétée par le shell externe et interactif. … (Suite)
sh -cshell 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=valuechaîne à l'environnement que l'écho reçoit. Cependant, echone fait rien avec sa liste d'environnement et de toute façon, dans la plupart des shells, echoest 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 shcommande et shutilisons son environnement. Coquilles convertissent chacune des variables qu'ils reçoivent de leur environnement à une variable shell, de sorte que la varvariable d'environnement shreçoit sera converti en une $varvariable et quand il se dilate dans cette echoligne de commande, qui deviendront echo value. Parce que l'environnement est par défaut hérité, echorecevra également var=valuedans son environnement (ou le serait s'il était exécuté), mais encore une fois, echone 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 commanddevant 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 $TESTprovoque echode récupérer TESTenv 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 123Il crée les vars temporaires définis avant la commande. Il enregistre la valeur actuelle de TESTet la remplace par 456; la ligne de commande est maintenant
echo 123Il 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
>>
printenvutile 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=foos'exécute en tant qu'instruction distincte - elle n'est pas simplement définie dans le contexte de echo.