`env foo = bar echo $ foo` ничего не печатает

8

Я думаю, что у меня огромный мозговой перманент. Я бы ожидал

env foo=bar echo $foo

... для печати bar, но вместо этого я получаю пустую строку. Wat.

То же самое происходит, если я использую синтаксис bash:

foo=bar echo $foo
badp
источник

Ответы:

8

Аналогичный вопрос был дан ответ в последнее время : символы оцениваются в линии до того , как символ определен в этой линии, что делает необходимым разделить определение и использование символов в отдельных строках.

По комментарию вы могли бы сделать это:

foo=bar bash -c 'echo $foo'

который сначала присваивает значение fooи передает его в новый процесс в качестве переменной среды, где оно может быть напечатано.

Вы можете прочитать больше об этом в POSIX Shell Command Language распознавание токенов .

В продолжение комментария @mikeserv :

  • POSIX не является достаточно явным, чтобы дать полный ответ.
  • В начале цитируемого раздела говорится

    Оболочка должна читать свои входные данные в виде строк из файла, из терминала в случае интерактивной оболочки или из строки в случае sh -c или system ().

  • в конце говорится

    Как только токен разграничен, он классифицируется в соответствии с требованиями грамматики Shell.

  • но POSIX не говорит явно, что вся строка разбита на токены перед работой над грамматикой.
  • в этом случае мы полагаемся на существующую практику - оболочка соответствует, поскольку ничто не противоречит письменному стандарту, но стандарт не может использоваться для прогнозирования поведения во всех случаях.
  • этот же комментарий относится, конечно, к поведению псевдонимов (вот почему я назвал его похожим вопросом).
Томас Дики
источник
или если ты в порядке с цитированием ада,env foo=bar bash -c 'echo $foo'
badp
На самом деле вопрос псевдонима основан на том, что секция распознавания токенов подразумевает, что все токены вычисляются для данной строки перед переходом к грамматике. Но для обоих стандартов стандарт не является явным , что заставляет вас полагаться на существующую практику.
Томас Дики
@thomasdickey - да, это тоже была моя суть. вы знаете, когда вы пишете комментарий, если вы сделаете это, @username...commentуказанный вами пользователь получит небольшое сообщение, сообщающее им, что вы разговаривали с ним. хорошо, они будут, если его нить актуальна.
mikeserv
@mikeserv (как это). хм - я буду помнить это (хотя, как это работает со встроенными пробелами, не было очевидно).
Томас Дики
как это. тангенциально, я имел взгляд на luit.cи я думаю , что я могу просто изменить , setup_io(){ ... ;fnctl(0, [GS]ETFL, 0);...}чтобы сделать 2для первого аргумента. ну, я думаю, что copyTermios()и setRawTermios()функции, возможно, тоже нужно немного изменить, но я думаю, что все должно быть просто. rc = (return)для каждой строки , кажется странным , - но я не C программистов либо. это ваша вещь или это досталось по наследству? и если ваш пустой комментарий относится к "${set_null_var:=new val and $(echo other stuff)}"вам, вы в большей степени в безопасности. некоторые снаряды будут делать странные вещи с }.
mikeserv