`env foo = bar echo $ foo` n'imprime rien

8

Je pense que j'ai un énorme brainfart. Je m'attendrais

env foo=bar echo $foo

... à imprimer bar, mais j'obtiens une ligne vide à la place. Wat.

La même chose se produit si j'utilise la syntaxe bash:

foo=bar echo $foo
badp
la source

Réponses:

8

Une question similaire a reçu une réponse récemment : les symboles sont évalués dans la ligne avant que le symbole ne soit défini dans cette ligne, ce qui rend nécessaire de diviser la définition et l'utilisation des symboles pour séparer les lignes.

Invité par un commentaire, vous auriez pu le faire:

foo=bar bash -c 'echo $foo'

qui attribue d'abord une valeur à fooet la transmet à un nouveau processus en tant que variable d'environnement où elle peut être imprimée.

Vous pouvez en savoir plus à ce sujet dans la reconnaissance du jeton de langage de commande POSIX Shell .

Suite au commentaire de @mikeserv :

  • POSIX n'est pas suffisamment explicite pour donner la réponse complète.
  • Au début de la section citée, il est dit

    Le shell doit lire son entrée en termes de lignes à partir d'un fichier, d'un terminal dans le cas d'un shell interactif, ou d'une chaîne dans le cas de sh -c ou de system ().

  • à la fin, ça dit

    Une fois qu'un jeton est délimité, il est classé comme requis par la grammaire de Shell Grammar.

  • mais POSIX ne dit pas explicitement que la ligne entière est symbolisée avant de travailler sur la grammaire.
  • dans ce cas, nous nous appuyons sur la pratique existante - le shell est conforme car rien ne contredit la norme écrite, mais la norme ne peut pas être utilisée pour prédire le comportement dans tous les cas.
  • le même commentaire s'applique, bien sûr, au comportement des alias (c'est pourquoi je l'ai appelé une question similaire ).
Thomas Dickey
la source
ou si vous êtes d'accord pour citer l'enfer,env foo=bar bash -c 'echo $foo'
badp
En fait, la question des alias repose sur l'implication de la section de reconnaissance des jetons selon laquelle les jetons sont tous calculés pour une ligne donnée avant de passer à la grammaire. Mais pour les deux, la norme n'est pas explicite , ce qui vous fait vous fier à la pratique existante.
Thomas Dickey
@thomasdickey - ouais, c'était aussi mon point essentiel. vous savez, lorsque vous écrivez un commentaire si vous faites @username...commentl'utilisateur que vous spécifiez recevra un petit message leur faisant savoir que vous leur parliez. eh bien, ils le feront si son thread est pertinent.
mikeserv
@mikeserv (comme ça). hmm - je garderai cela à l'esprit (bien que la façon dont cela fonctionne avec les blancs intégrés n'était pas apparente).
Thomas Dickey
comme ça. tangentiellement, j'ai regardé luit.cet je pense que je peux changer setup_io(){ ... ;fnctl(0, [GS]ETFL, 0);...}à faire 2pour le premier argument. eh bien, je suppose que les fonctions copyTermios()et setRawTermios()pourraient également avoir besoin d'une petite modification, mais cela devrait être simple, je pense. le rc = (return)pour chaque ligne semble étrange - mais je ne suis pas non plus un programmeur C. est-ce votre truc ou est-ce hérité? et si votre commentaire en blanc fait référence à "${set_null_var:=new val and $(echo other stuff)}"vous êtes en grande partie en sécurité avec quoi que ce soit. certains obus feront des trucs bizarres avec }.
mikeserv