Błąd „oczekiwanie jednego operatora” w Bash, jeśli warunek

225

Próbowałem dowiedzieć się, co jest z tym nie tak, ale po prostu nie mogę tego zrozumieć.

W tej części pojawia się błąd.

elif [ $operation = "man" ]; then
    if [ $aug1 = "add" ]; then         # <- Line 75
    echo "Man Page for: add"
    echo ""
    echo "Syntax: add [number 1] [number 2]"
    echo ""
    echo "Description:"
    echo "Add two different numbers together."
    echo ""
    echo "Info:"
    echo "Added in v1.0"
    echo ""
elif [ -z $aug1 ]; then
    echo "Please specify a command to read the man page."
else
    echo "There is no manual page for that command."
fi

Otrzymuję ten błąd:

calc_1.2: line 75: [: =: unary operator expected
Jordanss10
źródło
4
Myślę, że twoje ifoświadczenie w linii 75 potrzebuje fi.
Steve,
7
W razie wątpliwości cytuj zmienne.
koola
9
@koola, „zawsze” cytuje zmienne.
CousinCocaine

Odpowiedzi:

480

Jeśli wiesz, że zawsze będziesz używać bash, o wiele łatwiej jest zawsze użyć polecenia złożonego z podwójnym nawiasiem [[ ... ]], zamiast wersji pojedynczego nawiasu zgodnej z Posix [ ... ]. Wewnątrz [[ ... ]]związku dzielenie słów i rozwijanie nazw ścieżek nie są stosowane do słów, więc możesz na nich polegać

if [[ $aug1 == "and" ]];

aby porównać wartość $aug1z łańcuchem and.

Jeśli używasz [ ... ], zawsze musisz pamiętać o podwójnym cytowaniu zmiennych:

if [ "$aug1" = "and" ];

Jeśli nie zacytujesz rozszerzenia zmiennej, a zmienna jest niezdefiniowana lub pusta, znika z miejsca przestępstwa, pozostawiając tylko

if [ = "and" ]; 

która nie jest prawidłową składnią. (Nie powiedzie się również z innym komunikatem o błędzie, jeśli zostanie $aug1uwzględniony biały znak lub metaznaki powłoki).

Nowoczesny [[operator ma wiele innych fajnych funkcji, w tym dopasowanie wyrażeń regularnych.

rici
źródło
9
"nowoczesny"? Czy [[ zawsze był w bash? Jest w skorupie Korna od ponad dwudziestu lat i jest ostry. (Wiem, co masz na myśli)
cdarke
31

Zajęło mi to trochę czasu, aby to znaleźć, ale zauważ, że jeśli masz błąd spacji, otrzymasz również ten sam błąd:

[: =: unary operator expected

Poprawny:

if [ "$APP_ENV" = "staging" ]

vs

if ["$APP_ENV" = "staging" ]

Jak zawsze ustawienie -xzmiennej debugowania pomaga znaleźć:

set -x
Juha Vehnia
źródło
Ktoś przekazał mi ten błąd w skrypcie kompilacji. Oszczędź mi trochę czasu, dzięki!
Kyle
8

Spróbuj przypisać wartość $aug1przed użyciem jej w if[]instrukcjach; komunikat o błędzie zniknie później.

Yilee
źródło
0

mówisz ... :

elif [$ operation = "man"]; to jeśli [$ aug1 = "add"]; następnie # <- Wiersz 75 echa „Strona man dla: dodaj„ echo ”„ echo ”Składnia: dodaj [liczba 1] [liczba 2]„ echo ”„ echo ”Opis:„ echo ”Dodaj dwie różne liczby razem.” echo „„ ​​echo ”Informacje:„ echo ”Dodano w wersji 1.0„ echo ”„ elif [-z $ aug1]; następnie echo „Podaj polecenie, aby odczytać stronę podręcznika”. w przeciwnym razie echo „Nie ma strony podręcznika dla tego polecenia.” fi

myślę, że to tylko przestrzeń ... lubię to:

elif [$operation = "man"]; then
    if [ $aug1 = "add" ]; then         # <- Line 75
    echo "Man Page for: add"
    echo ""
    echo "Syntax: add [number 1] [number 2]"
    echo ""
    echo "Description:"
    echo "Add two different numbers together."
    echo ""
    echo "Info:"
    echo "Added in v1.0"
    echo ""
elif [-z $aug1]; then
    echo "Please specify a command to read the man page."
else
    echo "There is no manual page for that command."
fi
Renan Moura
źródło
-11

Możesz także ustawić wartość domyślną dla zmiennej, więc nie musisz używać dwóch „[”, co odpowiada dwóm procesom („[” to tak naprawdę program) zamiast jednego.

Ma następującą składnię: $ {VARIABLE: -default}.

Cała sprawa musi być przemyślana w taki sposób, że ta „domyślna” wartość różni się od „prawidłowej” wartości / treści.

Jeśli z jakiegoś powodu nie jest to możliwe, prawdopodobnie należy dodać krok, np. Sprawdzenie, czy w ogóle jest jakaś wartość, podobnie jak „if [-z $ VARIABLE]; następnie powtórz„ zmienna musi być wypełniona ”” lub „ jeśli [! -z $ VARIABLE]; wtedy # wszystko jest w porządku, kontynuuj resztę skryptu ".

el guesto
źródło
3
[[nie odradza dwóch procesów, jest to wbudowana powłoka (i [jest także wbudowana w Bash). [[różni się od [ [, który traktuje drugi [jako ciąg znaków
użytkownik123444555621