2

Я работал всю свою жизнь в оболочке HPUX/ksh, поэтому bash в наши дни, похоже, предлагает новые способы выполнения многих задач (многие из которых не соответствуют требованиям POSIX - например, 'mkdir -p /root / {abc), def, ghi, jkl} '- по-видимому, это рекомендация по кодированию, лучшая практика в bash / OpenStack - но это совсем другое дело).

В любом случае, я видел такой вид выполнения скрипта в нескольких местах в коде OpenStack:

ENABLE_VCENTER=true bash /root/stack_install.sh

Может кто-нибудь объяснить, как это работает - я знаю, что оболочка установит переменную и затем вызовет сценарий оболочки (что объясняет классическую ошибку nooB, почему назначение переменных не должно быть с пробелами - например. ПРИВЕТ = мир). Но что именно происходит внутри?

Кроме того, почему это не работает для меня, когда я пытаюсь эту команду:

HELLO=world echo $HELLO

Я получаю следующий вывод из оболочки:

[ ubuntuOne : /home/bumblebee ]
> HELLO=world echo $HELLO


[ ubuntuOne : /home/bumblebee ]
> 

Что мне здесь не хватает?

Спасибо за ваши ответы.

1 ответ1

2
HELLO=world echo $HELLO

В приведенном выше bash выполняет раскрытие параметров перед выполнением оператора. Это означает, что $HELLO заменяется ничем (или каким-либо другим текущим значением HELLO) перед выполнением оператора (что будет включать установку HELLO в world).

Заметим:

$ HELLO=world bash -c 'echo $HELLO'
world

Обратите внимание, что echo $HELLO находится внутри одинарных кавычек. Одинарные кавычки предотвращают расширение параметров. Это означает, что HELLO не будет оцениваться до тех пор, пока не будет запущена оболочка bash и не увидит в ней аргумент К тому времени HELLO станет равным world .

Напротив, рассмотрим эту строку, в которой одинарные кавычки были заменены двойными кавычками:

$ HELLO=world bash -c "echo $HELLO"

Здесь ничего не печатается, потому что двойные кавычки не подавляют расширение параметра. Таким образом, команде bash задаются два аргумента -c и echo . Следовательно, ничего не печатает.

Все кровавые детали

man bash подробно объясняет, что происходит, когда обрабатываются такие команды, как приведенные выше:

Когда выполняется простая команда, оболочка выполняет следующие расширения, назначения и перенаправления слева направо.

   1.     The words that  the  parser  has  marked  as  variable
          assignments  (those  preceding  the  command name) and
          redirections are saved for later processing.

   2.     The words that are not variable assignments  or  redi‐
          rections  are  expanded.   If  any  words remain after
          expansion, the first word is taken to be the  name  of
          the command and the remaining words are the arguments.

   3.     Redirections  are  performed  as described above under
          REDIRECTION.

   4.     The text after  the  =  in  each  variable  assignment
          undergoes  tilde  expansion, parameter expansion, com‐
          mand substitution,  arithmetic  expansion,  and  quote
          removal before being assigned to the variable.

Рассмотрим снова команду:

HELLO=world echo $HELLO

Аргумент echo подвергается расширению параметра на шаге 2, в то время как bash даже не начинает присваивать новое значение HELLO до шага 4.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .