`env foo = bar echo $ foo` não imprime nada


8

Eu acho que estou tendo um enorme peido cerebral. eu esperaria

env foo=bar echo $foo

... para imprimir bar, mas recebo uma linha vazia. Wat.

O mesmo acontece se eu usar a sintaxe do bash:

foo=bar echo $foo

Respostas:


8

Uma pergunta semelhante foi respondida recentemente : os símbolos são avaliados na linha antes que o símbolo seja definido nesta linha, tornando necessário dividir a definição e o uso dos símbolos para separar as linhas.

Solicitado por um comentário, você poderia ter feito isso:

foo=bar bash -c 'echo $foo'

que primeiro atribui um valor fooe o passa para um novo processo como uma variável de ambiente onde pode ser impresso.

Você pode ler mais sobre isso no reconhecimento do POSIX Shell Command Language Token .

Seguindo o comentário do @mikeserv :

  • O POSIX não é explícito o suficiente para fornecer a resposta completa.
  • No início da seção citada, diz

    O shell deve ler sua entrada em termos de linhas de um arquivo, de um terminal no caso de um shell interativo ou de uma string no caso de sh -c ou system ().

  • no final, diz

    Depois que um token é delimitado, ele é categorizado conforme exigido pela gramática na Gramática do Shell.

  • mas o POSIX não diz explicitamente que toda a linha é tokenizada antes de trabalhar na gramática.
  • nesse caso, contamos com a prática existente - o shell está em conformidade porque nada contradiz o padrão escrito, mas o padrão não pode ser usado para prever o comportamento em todos os casos.
  • o mesmo comentário se aplica, é claro, ao comportamento dos pseudônimos (razão pela qual me referi a ele como uma pergunta semelhante ).

ou se você está bem com citando o inferno,env foo=bar bash -c 'echo $foo'
— badp

Na verdade, a questão do alias se baseia na implicação da seção de reconhecimento de token de que os tokens são todos computados para uma determinada linha antes de passar para a gramática. Mas, para ambos, o padrão não é explícito , fazendo você confiar na prática existente.
— Thomas Dickey

@ thomasdickey - sim, essa era minha essência também. quando você escreve um comentário, se você @username...commentespecificar o usuário especificado, receberá uma pequena mensagem informando que você estava conversando com ele. bem, eles serão relevantes para o segmento.
— mikeserv

@mikeserv (assim). hmm - vou ter isso em mente (apesar de como ele funciona com espaços em branco incorporados não era aparente).
— Thomas Dickey

Curtiu isso. tangencialmente, eu tinha uma olhada luit.ce eu acho que eu posso apenas mudar setup_io(){ ... ;fnctl(0, [GS]ETFL, 0);...}a fazer 2para o primeiro argumento. bem, acho que as funções copyTermios()e setRawTermios()também precisam de uma pequena modificação, mas acho que deve ser simples. o rc = (return)para cada linha parece estranho - mas também não sou programador de C. isso é coisa sua ou foi herdada? e se o comentário dos espaços em branco se referir a "${set_null_var:=new val and $(echo other stuff)}"você, você estará praticamente seguro com qualquer coisa. algumas conchas fazem coisas estranhas }.
— mikeserv
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.