Пробелы в назначениях переменных в скриптах оболочки

17

В чем разница между назначениями переменных ниже?

var=23
var =23
var= 23
var = 23

Есть ли разница в пространстве вокруг оператора присваивания?

Аджай
источник
В большинстве языков программирования это не имеет никакого значения ... Есть ли разница для начала? Также вы говорите о старой школе здесь? не аш / зш / баш или другие новые вещи?
Cestarian
Только первые примеры устанавливают переменную.
DisplayName
Тогда разве последние 3 не генерируют синтаксическую ошибку? или они действительно имеют смысл?
Cestarian
2
@Cestarian они могут что-то значить, если у вас есть команда, которая будет вызываться, varто var =23она будет передана =23в var, и var = 23будет передана =и 23в var. Или, если у вас есть вызванная команда, var=тогда var= 23передайте 23команду var=.
DisplayName
1
@Cestarian Заменено на bash, что делает то же самое, что и shво всех четырех случаях.
pfnuesel

Ответы:

14

Это очень зависит от оболочки. Если мы рассмотрим только 4 основных семейства раковин (Bourne, csh, rc, fish):

Семья Борн

Это Bourne оболочки и все его варианты и ksh, bash, ash/ dash, zsh, yash.

  • var=23: это правильный синтаксис присваивания переменной: слово, которое состоит из букв без кавычек, цифр или подчеркиваний, за которыми следует символ без кавычек, =который появляется перед аргументом команды (здесь он сам по себе)
  • var =23, То varкоманда с в =23качестве аргумента ( за исключением , zshкогда =somethingэто специальный оператор , который расширяется на пути somethingкоманды. Здесь, вы бы , вероятно, получите ошибку , как 23вряд ли будет действительным именем команды).
  • var= 23: назначение, var=за которым следует имя команды 23. Это предназначено для выполнения 23с var=переданным в его окружение ( varпеременная окружения с пустым значением).
  • var = 23, varКоманда с =и в 23качестве аргумента. Попробуйте, echo = 23например.

Csh семья

cshи tcsh. Переменные присваиваются с использованием set var = valueсинтаксиса для скалярных переменных, set var = (a b)для массивов, setenv var valueдля переменных среды, @ var=1+1для присваивания и арифметической оценки.

Так:

  • var=23просто вызывает var=23команду.
  • var =23вызывает varкоманду в =23качестве аргумента.
  • var= 23вызывает var=команду в 23качестве аргумента
  • var = 23вызывает varкоманду с =и в 23качестве аргументов.

Rc семья

Вот rc, esи akanga. В этих оболочках переменные - это массивы, и присваивания имеют var = (foo bar), с var = fooсокращением var = (foo)(массив с одним fooэлементом) и var =сокращением var = ()(массив без элемента, используйте var = ''для массива с одним пустым элементом).

В любом случае, пробелы (пробел или табуляция) вокруг =допустимы и необязательны. Таким образом, в этих оболочках эти 4 команды эквивалентны и эквивалентны var = (23)назначению массива с одним элементом 23.

Рыбы

В fish, синтаксис присваивания переменной есть set var value1 value2. Как и в rc, переменные являются массивами.

Таким образом, поведение будет таким же, как с csh, за исключением того, что fishвы не сможете запустить команду с =именем в имени. Если у вас есть такая команда есть, вам нужно вызвать его с помощью sh, например: sh -c 'exec weird===cmd'.

Так все var=23и var= 23даст вам ошибку, var =23будет вызывать varкоманду с в =23качестве аргумента и var = 23будет вызывать varкоманду с =и в 23качестве аргументов.

Стефан Шазелас
источник
8

var=23присваивает 23 переменной var.

var =23пытается выполнить команду (или псевдоним, или функцию) varс аргументом=23

var = 23То же самое, но аргументы =и23

var= 23устанавливает varпеременную окружения в пустую строку, затем запускает команду23

Да, оболочка странная как язык программирования. Но это имеет смысл в качестве оболочки для интерактивного использования, где пробелы разделяют команды и аргументы. Большинство «специальных символов» ( =в данном случае) имеют специальное значение только в определенных позициях, чтобы допускать почти произвольные аргументы для команд. См. Приведенные выше интерпретации.

vonbrand
источник
3
  • var=23 правильный синтаксис для присвоения значения переменной.
  • var =23рассматривается как команда varс =23опцией / аргументом для команды var(хотя правильный / стандартный синтаксис для аргумента / опции - -optionили --option)
  • var= 23не будет назначать ничего, varпоскольку пробел нарушает процесс назначения и 23будет рассматриваться как другая команда. Обходной путь var=\ 23или var=' 23'для хранения пробела.
  • var = 23имеет эффект, аналогичный описанному во втором случае.

    На самом деле этот тип использования пространства вокруг =обычно используется в условиях тестирования внутри [[ ]]. Пример для Bash:

    string1 = string2
           True if the strings are equal.  = should be used with the test command  for  POSIX  conformance.  
           When used with the [[ command, this performs pattern matching as described above (Compound Commands).

И в конце концов поведение пустого пространства вокруг =зависит от вашей оболочки и языков программирования.

Pandya
источник