Błąd polecenia nie znaleziono w przypisaniu zmiennej Bash


520

Mam ten skrypt o nazwie test.sh:

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

kiedy biegam sh test.sh, dostaję to:

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

Co ja robię źle? Patrzę na bardzo podstawowe / dla początkujących tutoriale skryptów bash online i tak mówią o deklarowaniu zmiennych ... Więc nie jestem pewien, co robię źle.

Jestem na Ubuntu Server 9.10. I tak, bash znajduje się w /bin/bash.


49
Cieszę się, że zadałeś pytanie, nie jesteś jedynym bobem tam!
młynarza goryla

6
Dzięki, że zadałeś to pytanie. Nie należy się wstydzić tego pytania. Pracuję do późna w nocy w biurze i nie ma wokół mnie eksperta Bash, który by na to odpowiedział.
Adway Lele,

3
Obecnie (prawie siedem lat później!) Istnieje liniowy / analizator FOSS o nazwie shellcheck , który automatycznie wykryje tę i inne typowe problemy ze składnią. Można go używać online lub zainstalować offline i zintegrować z edytorem.
ten drugi facet


Polecam użyć: #!/usr/bin/env bashzamiast wstawiać bezpośrednio, #!/bin/bashchyba że masz absolutną pewność, że jesteś bashw związku /binz tą odpowiedzią: stackoverflow.com/a/21613044/3589567
Alejandro Blasco

Odpowiedzi:


928

Nie możesz mieć spacji wokół znaku „=”.

Kiedy piszesz:

STR = "foo"

bash próbuje uruchomić polecenie o nazwie STR z 2 argumentami (ciągi „=” i „foo”)

Kiedy piszesz:

STR =foo

bash próbuje uruchomić polecenie o nazwie STR z 1 argumentem (ciąg „= foo”)

Kiedy piszesz:

STR= foo

bash próbuje uruchomić polecenie foo z STR ustawionym na pusty ciąg znaków w swoim środowisku.

Nie jestem pewien, czy to pomaga wyjaśnić, czy jest to zwykłe zaciemnianie, ale pamiętaj, że:

  1. Pierwsze polecenie jest dokładnie równoważne: STR "=" "foo",
  2. drugi jest taka sama jak STR "=foo",
  3. a ostatni jest równoważny z STR="" foo.

Odpowiednia sekcja specyfikacji języka sh, sekcja 2.9.1, stanowi:

„Proste polecenie” jest sekwencją opcjonalnych przypisań zmiennych i przekierowań, w dowolnej sekwencji, opcjonalnie poprzedzonych słowami i przekierowaniami, zakończonych operatorem sterującym.

W tym kontekście a wordto polecenie, które uruchomi bash. Każdy ciąg zawierający =(w dowolnej pozycji innej niż na początku ciągu), który nie jest przekierowaniem, jest przypisaniem zmiennej, natomiast każdy ciąg, który nie jest przekierowaniem i nie zawiera, =jest poleceniem. W STR = "foo", STRnie jest zmienną przyporządkowanie.


2
Jeśli masz zmienną o nazwie zawierającej „-”, występuje ten sam błąd. W takim przypadku rozwiązaniem jest usunięcie „-”
chomp

1
chomp @ W regule 7b sekcji 2.10.10 pubs.opengroup.org/onlinepubs/9699919799 „Jeśli wszystkie znaki poprzedzające„ = ”tworzą prawidłową nazwę (patrz Nazwa XBD), token ASSIGNMENT_WORD zostanie zwrócony.” Po linku do sekcji 3.231 pubs.opengroup.org/onlinepubs/9699919799 znajdujemy „W języku poleceń powłoki słowo składające się wyłącznie z podkreśleń, cyfr i alfabetu z przenośnego zestawu znaków. Pierwszy znak nazwy to nie cyfra. ”. Zatem słowo FOO-BAR=quxnie jest przypisaniem zmiennej, ponieważ FOO-BARnie jest prawidłową nazwą.
William Pursell

2
Oferuję nagrodę za nagrodzenie tego jasnego wyjaśnienia na zawsze powszechny problem dla początkujących (no cóż, a także, aby móc go znaleźć szybciej, gdy chcę go połączyć: D). Dzięki za ułatwienie!
fedorqui „SO przestań szkodzić”

1
@fedorqui Thanks! Nie jestem do końca przekonany, czy to jasne wyjaśnienie i często zastanawiam się, czy można to uprościć.
William Pursell,

159

Upuść spacje wokół =znaku:

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

9
Jest to jednak zabawne, podobnie jak set foo = barczęsty błąd w plikach wsadowych systemu Windows - i tam wyśmiewa go język wsadowy ;-)
Joey

Dzięki @joey. Utknąłem w pisaniu skryptu powłoki, w którym inicjowałem zmienne spacjami po „=”. Uratowałeś mi dzień
Lalit Rao

Dlaczego bash nie przyjmuje liczb w lewym polu? jak 3 = „Hello World”, narzeka na brak polecenia
Freedo

6

W trybie interaktywnym wszystko wygląda dobrze:

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

Oczywiście (!), Jak powiedział Johannes, nie ma miejsca wokół =. Jeśli wokół jest jakaś przestrzeń, =wówczas w trybie interaktywnym wyświetla błędy jako

Nie znaleziono polecenia „str”


2
Ale zauważ, że OP mówił STR = "Hello World", więc ta odpowiedź nie ma tutaj zastosowania.
fedorqui „SO przestań szkodzić”

@Arkapravo, co oznacza tryb interaktywny, czy ma to coś wspólnego ze $znakiem
Kasun Siyambalapitiya

@KasunSiyambalapitiya przez „tryb interaktywny” oznacza pisanie tych poleceń w rzeczywistym terminalu, a nie w skrypcie.
numbermaniac

5

Wiem, że na to pytanie udzielono odpowiedzi bardzo wysokiej jakości. Krótko mówiąc, nie możesz mieć spacji.

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

Nie działał z powodu odstępów wokół znaku równości. Gdybyś miał biec ...

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

To by działało


2

Kiedy definiujesz dowolną zmienną, nie musisz wstawiać żadnych dodatkowych spacji.

Na przykład

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

Więc usuń spacje:

name="Stack Overflow" 

i będzie dobrze działać.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.