`env foo = bar echo $ foo` non stampa nulla


8

Penso che stia avendo un grande cervello. Mi aspetterei

env foo=bar echo $foo

... per stampare bar, ma ottengo invece una riga vuota. Wat.

Lo stesso succede se uso la sintassi bash:

foo=bar echo $foo

Risposte:


8

Di recente è stata data una domanda simile : i simboli vengono valutati nella riga prima che il simbolo venga definito in questa riga, rendendo necessario dividere la definizione e l'uso dei simboli per separare le righe.

Spinto da un commento, avresti potuto fare questo:

foo=bar bash -c 'echo $foo'

che per primo assegna un valore fooe lo passa in un nuovo processo come variabile d'ambiente in cui può essere stampato.

Puoi leggere di più al riguardo nel riconoscimento dei token del linguaggio dei comandi della shell POSIX .

A seguito del commento di @mikeserv :

  • POSIX non è abbastanza esplicito per dare l'intera risposta.
  • All'inizio della sezione citata, dice

    La shell deve leggere il suo input in termini di righe da un file, da un terminale nel caso di una shell interattiva o da una stringa nel caso di sh -c o system ().

  • alla fine, dice

    Una volta delimitato, un token viene classificato come richiesto dalla grammatica in Shell Grammar.

  • ma POSIX non dice esplicitamente che l'intera riga è tokenizzata prima di lavorare sulla grammatica.
  • in quel caso, ci affidiamo alla pratica esistente: la shell si conforma perché nulla contraddice lo standard scritto, ma lo standard non può essere usato per prevedere il comportamento in tutti i casi.
  • lo stesso commento si applica, ovviamente, al comportamento degli alias (motivo per cui l'ho definito una domanda simile ).

o se stai bene citando l'inferno,env foo=bar bash -c 'echo $foo'
badp

In realtà, la domanda alias si basa sull'implicazione della sezione di riconoscimento dei token secondo cui i token vengono tutti calcolati per una determinata riga prima di passare alla grammatica. Ma per entrambi, lo standard non è esplicito , facendo affidamento sulla pratica esistente.
Thomas Dickey,

@thomasdickey - sì, anche quello era il mio succo. sai, quando scrivi un commento se lo fai @username...commentl'utente che specifichi riceverà un piccolo messaggio per far loro sapere che stavi parlando con loro. bene, lo faranno se è rilevante per il thread.
Mikeserv,

@mikeserv (come questo). hmm - Lo terrò a mente (anche se il modo in cui funziona con gli spazi bianchi non era evidente).
Thomas Dickey,

come quello. tangenzialmente, ho dato un'occhiata luit.ce penso di poter semplicemente cambiare setup_io(){ ... ;fnctl(0, [GS]ETFL, 0);...}per fare 2per il primo argomento. bene, immagino che anche le funzioni copyTermios()e setRawTermios()potrebbero aver bisogno di una piccola modifica, ma dovrebbe essere semplice, credo. il rc = (return)per ogni riga sembra strano - ma non sono neanche un programmatore C. è questa la tua cosa o è stata ereditata? e se il tuo commento sugli spazi vuoti si riferisce a "${set_null_var:=new val and $(echo other stuff)}"sei per lo più al sicuro con qualsiasi cosa. alcune conchiglie faranno cose strane con }.
Mikeserv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.