Команда не знайдена помилка у призначенні змінної Bash


520

У мене цей сценарій називається test.sh:

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

коли я біжу, sh test.shя отримую це:

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

Що я роблю неправильно? Я дивлюся на надзвичайно основні / початківці підручники з сценарію сценарію в Інтернеті, і ось, як вони кажуть, оголошувати змінні ... Тож я не впевнений, що я роблю не так.

Я на Ubuntu Server 9.10. І так, баш розташований в /bin/bash.


49
Я радий, що ти поставив запитання, ти не єдиний баш-ноб!
мельник горили

6
Дякуємо, що задали це запитання. Це не питання, яке повинно бентежити. Я працюю пізно вночі в офісі, і навколо мене немає експерта Баша, який би відповів на це.
Адвей Леле

3
У ці дні (майже через сім років!) З'явився лінійчик / аналізатор FOSS під назвою shellcheck, який автоматично виявить цю та інші поширені проблеми з синтаксисом. Його можна використовувати в Інтернеті або встановити в автономному режимі та інтегрувати у ваш редактор.
той інший хлопець


Я б рекомендував вам скористатися: #!/usr/bin/env bashзамість того, щоб безпосередньо звертатись, #!/bin/bashякщо ви абсолютно не впевнені, що у вас bashє, /binчерез цю відповідь: stackoverflow.com/a/21613044/3589567
Алехандро Бласко,

Відповіді:


928

У вас не може бути пробілів навколо знаку '='.

Коли ви пишете:

STR = "foo"

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

Коли ви пишете:

STR =foo

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

Коли ви пишете:

STR= foo

bash намагається запустити командний foo з STR, встановленим на порожній рядок у своєму оточенні.

Я не впевнений, чи це допомагає уточнити, чи це просто запаморочення, але зауважте, що:

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

У відповідному розділі специфікації мови, розділ 2.9.1 зазначено:

"Проста команда" - це послідовність необов'язкових присвоєнь змінних та перенаправлень у будь-якій послідовності, необов'язково слідуючи за словами та перенаправленнями, завершеними оператором управління.

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


2
Якщо у вас є змінна назва, яка містить "-", трапляється та сама помилка. У такому випадку рішенням буде усунути "-"
чмокання

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). Дякуємо, що полегшили справи!
fedorqui 'ТАК перестаньте шкодити'

1
@fedorqui Дякую! Я не зовсім впевнений, що це чітке пояснення, і мені часто цікаво, чи можна це зробити простіше.
Вільям Перселл

159

Відкиньте пробіли навколо =знака:

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

9
Це смішно, хоча set foo = barце також поширена помилка і в пакетних файлах Windows - і там пакетна мова висміюється за це ;-)
Joey

Дякую @joey Я застряг у написанні сценарію оболонки, де я ініціалізував змінні з пробілами після "=". Ти врятував мій день
Лаліт Рао

Чому bash не приймає числа в лівому полі? як 3 = "Hello World", він скаржиться на те, що команду не знайдено
Freedo

6

В інтерактивному режимі все виглядає добре:

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

Очевидно (!) Як сказав Йоганнес, місця навколо немає =. У випадку, якщо навколо =в ньому є пробіл, то в інтерактивному режимі він видає помилки як

Не знайдено команди "str"


2
Але зауважте, що ОП говорила STR = "Hello World", тому ця відповідь тут не застосовується.
fedorqui 'ТАК перестаньте шкодити'

@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" 

і це буде добре працювати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.