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?
shell
environment-variables
echo
ashleysmithgpu
la source
la source
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
ç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, voirhelp export
). Si vous avez seulement besoin que la variable apparaisse dans l'environnement d'une commande, utilisez ce que vous avez essayé, à savoir:la source
$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 queecho
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 pasecho
de sortir le contenu de la variableTEST
depuis son environnement. Il demande au shell de fonctionnerecho
avec l'argument comme étant tout ce qui se trouve actuellement dans la variable appeléeTEST
- 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'ilecho "$var"
s'agit de guillemets simples, cette chaîne entière est transmise aush -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
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
Cela aurait été une autre affaire. Ici, nous passons
var=value
à lash
commande etsh
utilisons son environnement. Coquilles convertissent chacune des variables qu'ils reçoivent de leur environnement à une variable shell, de sorte que lavar
variable d'environnementsh
reçoit sera converti en une$var
variable et quand il se dilate dans cetteecho
ligne de commande, qui deviendrontecho value
. Parce que l'environnement est par défaut hérité,echo
recevra égalementvar=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):
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":
Avec zsh, vous pouvez utiliser des fonctions inline:
ou:
Avec bash et zsh (mais pas ash, pdksh ou AT & T ksh), cette astuce fonctionne aussi:
Une variante qui fonctionne en quelques coquilles (plus
dash
,mksh
,yash
) mais paszsh
(sauf danssh
/ksh
émulation):(utiliser
command
devant un shell spécial (icieval
) dans les shells POSIX supprime leur particularité (ici, les affectations de variables d'entre eux restent en vigueur après leur retour))la source
Vous le faites correctement, mais la syntaxe bash est facile à interpréter de manière erronée: vous pouvez penser que cela
echo $TEST
provoqueecho
de récupérerTEST
env var puis de l’imprimer, ce n’est pas le cas. Donc donnéensuite
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
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 maintenantIl 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:
la source
printenv
utile de tester / prouver le concept (se comporte comme un script, par opposition àecho
)Vous pouvez obtenir ce travail en utilisant:
la source
TEST=foo
s'exécute en tant qu'instruction distincte - elle n'est pas simplement définie dans le contexte deecho
.