Ошибка команды при назначении переменной Bash

521

У меня есть этот скрипт с именем test.sh:

#!/bin/bash
STR = "Hello World"
echo $STR

когда я бегу, sh test.shя получаю это:

test.sh: line 2: STR: command not found

Что я делаю неправильно? Я смотрю на очень простые / начинающие учебники по bash-скриптингу онлайн, и вот как они говорят, чтобы объявлять переменные ... Так что я не уверен, что делаю неправильно.

Я на Ubuntu Server 9.10. И да, Bash находится по адресу /bin/bash.

Джейк Уилсон
источник
49
Я рада, что вы задали вопрос, вы не единственный новичок на Bash!
Миллер горилла
6
Спасибо, что задали этот вопрос. Это не вопрос, который нужно смущать. Я работаю допоздна в офисе, и вокруг меня нет эксперта по Bash, который бы на это ответил.
Adway Lele
3
В эти дни (почти семь лет спустя!) Существует анализатор FOSS под названием shellcheck , который автоматически обнаруживает эту и другие распространенные проблемы синтаксиса. Он может быть использован онлайн или установлен в автономном режиме и интегрирован в ваш редактор.
тот другой парень
Смотрите также stackoverflow.com/questions/26971987/...
tripleee
Я бы порекомендовал вам использовать: #!/usr/bin/env bashвместо того, чтобы ставить напрямую, #!/bin/bashесли вы не уверены bashв том, /binчто вы находитесь из-за этого ответа: stackoverflow.com/a/21613044/3589567
Алехандро Бласко,

Ответы:

929

У вас не должно быть пробелов вокруг знака «=».

Когда вы пишете:

STR = "foo"

bash пытается запустить команду с именем STR с 2 аргументами (строки '=' и 'foo')

Когда вы пишете:

STR =foo

bash пытается запустить команду с именем STR с 1 аргументом (строка '= foo')

Когда вы пишете:

STR= foo

bash пытается запустить команду foo с STR, установленным в пустую строку в своем окружении.

Я не уверен, поможет ли это уточнить или это просто запутывание, но учтите, что:

  1. первая команда в точности эквивалентна: STR "=" "foo" ,
  2. второй такой же как STR "=foo" ,
  3. и последний эквивалентен STR="" foo.

Соответствующий раздел спецификации языка sh, раздел 2.9.1, гласит:

«Простая команда» - это последовательность необязательных присвоений и перенаправлений переменных, в любой последовательности, за которыми могут следовать слова и перенаправления, оканчивающиеся оператором управления.

В этом контексте a word- это команда, которую собирается запустить bash. Любая строка, содержащая =(в любой позиции, отличной от начала строки), которая не является перенаправлением, является присваиванием переменной, в то время как любая строка, которая не является перенаправлением и не содержит, =является командой. В STR = "foo", STRэто не присвоение переменной.

Уильям Перселл
источник
2
Если у вас есть переменная с именем, которое связывается с "-", происходит такая же ошибка. В этом случае решение состоит в том, чтобы удалить "-"
chomp
1
chomp @ В правиле 7b раздела 2.10.10 pubs.opengroup.org/onlinepubs/9699919799 «Если все символы, предшествующие« = », образуют правильное имя (см. Имя XBD), должен быть возвращен токен ASSIGNMENT_WORD». Перейдя по ссылке на раздел 3.231 pubs.opengroup.org/onlinepubs/9699919799 , мы находим «В языке команд оболочки слово, состоящее исключительно из подчеркиваний, цифр и алфавитов из переносимого набора символов. Первый символ имени не цифра ". Таким образом, слово FOO-BAR=quxне является присвоением переменной, поскольку FOO-BARне является допустимым именем.
Уильям Перселл
2
Я предлагаю вознаграждение, чтобы вознаградить это ясное объяснение всегда распространенной проблемой для начинающих (ну, а также, чтобы иметь возможность найти его быстрее, когда я захочу связать это: D). Спасибо за упрощение!
Федорки 'ТАК прекрати вредить'
1
@Fedorqui Спасибо! Я не совсем уверен, что это четкое объяснение, и я часто задаюсь вопросом, можно ли его упростить.
Уильям Перселл
159

Оставьте пробелы вокруг =знака:

#!/bin/bash 
STR="Hello World" 
echo $STR 
детеныш
источник
9
Это забавно, хотя, как set foo = barи обычная ошибка в пакетных файлах Windows, - и там язык пакета высмеивается за это ;-)
Joey
Спасибо @joey. Я застрял в написании сценария оболочки, где я инициализировал переменные с пробелами после "=". Вы спасли мой день
Лалит Рао
Почему bash не принимает числа в левом поле? like 3 = "Hello World", он жалуется на то, что команда не найдена
Freedo
6

В интерактивном режиме все выглядит нормально:

$ str="Hello World"
$ echo $str
Hello World

Очевидно (!), Как сказал Йоханнес, вокруг нет места =. Если =в интерактивном режиме есть свободное место, выдается ошибка:

Команда 'str' не найдена

Arkapravo
источник
2
Но обратите внимание, что ОП говорил STR = "Hello World", так что этот ответ здесь не применим.
Федорки 'ТАК прекрати вредить'
@Arkapravo, что означает интерактивный режим, имеет ли он какое-то отношение к $марке
Касун Сиямбалапития
@KasunSiyambalapitiya под «интерактивным режимом» он подразумевает ввод этих команд в реальном терминале, а не в скрипте.
Numbermaniac
5

Я знаю, что на это ответили очень качественным ответом. Но, короче говоря, у вас не может быть пробелов.

#!/bin/bash
STR = "Hello World"
echo $STR

Не работал из-за пробелов вокруг знака равенства. Если бы ты бежал ...

#!/bin/bash
STR="Hello World"
echo $STR

Это будет работать

Дерек Хабер
источник
2

Когда вы определяете какую-либо переменную, вам не нужно вводить лишние пробелы.

Например

name = "Stack Overflow"  
// it is not valid, you will get an error saying- "Command not found"

Итак, удалите пробелы:

name="Stack Overflow" 

и это будет работать нормально.

Рави Соланки
источник