Porównaj łańcuch używając powłoki sh

197

Używam powłoki SH i próbuję porównać ciąg z wartością zmiennej, ale ifwarunek jest zawsze wykonywany na true. Czemu?

Oto kod:

Sourcesystem="ABC"

if [ "$Sourcesystem" -eq 'XYZ' ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Nawet to nie działa:

Sourcesystem="ABC"

if [ 'XYZ' -eq "$Sourcesystem" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Po drugie, czy możemy dopasować to do NULL lub pustego ciągu?

James Bond
źródło
Po pierwsze w powłoce Bourne'a nie potrzebujesz dodatkowego ';' Kiedy testuję uruchamiając skrypt w powłoce Bourne'a, warunek if jest fałszywy. Najpierw pojawi się ostrzeżenie: [: ABC: oczekiwano wyrażenia typu integer. Wynik to: „System źródeł NIE jest dopasowany do ABC”. Jak komentują inni, -eq jest używane do porównań całkowitych. Użyj pojedynczego znaku równości do porównania ciągów w powłoce Bourne'a (#! / Bin / sh). Twoja powłoka powinna cię poprawić w pierwszej kolejności.
Kemin Zhou
6
Głosowanie za ponownym otwarciem. Cytowane dupki dotyczą powłoki bash, a nie anemicznej powłoki sh, która czasami jest powłoką Posix lub Dash.
jww
1
Zgoda i głosowanie. shi bashmają taki sam związek jak Ci C++. Nawet jeśli kod napisany dla pierwszego jest ważny w drugim, odpowiedzi dla drugiego nie można ufać, że zadziałają w pierwszym.
btilly

Odpowiedzi:

290

Do =porównania ciągów należy użyć operatora:

Sourcesystem="ABC"

if [ "$Sourcesystem" = "XYZ" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

man testmówi, że używasz -zdo dopasowania do pustych ciągów.

Mithrandir
źródło
2
Nie trzeba cytować ABCani XYZ.
ceving
29
Jeśli zmienna może zawierać spacje, konieczne jest cytowanie.
William Everett
1
Poprawiono przykład, aby ta część była bardziej przejrzysta @WilliamEverett.
Per Lundberg
83

-eqsłuży do porównywania liczb całkowitych. Użyj =zamiast tego.

Piotr Praszmo
źródło
5
I zwróć uwagę, aby nie używać podwójnej równości "=="
Rodrigo Caballero
36

eq służy do porównywania liczb całkowitych, zamiast tego użyj równego `` = '', przykład:

if [ 'AAA' = 'ABC' ];
then 
    echo "the same" 
else 
    echo "not the same"
fi

powodzenia

Qign20
źródło
Uwaga: jeśli porównujesz zmienne, upewnij się, że używasz, "$VAR"a nie tylko$VAR
Sridhar Sarnobat
22

Miałem ten sam problem, zrób to

if [ 'xyz' = 'abc' ];
then
echo "match"
fi

Zwróć uwagę na spacje. W tym przypadku ważne jest, aby użyć spacji przed i po =znaku.

Sprawdź „ Inne operatory porównania ”.

Eswar Yaganti
źródło
1
w Dockerfile / bin / sh: 1: [: =: nieoczekiwany operator
holms
10

-eqjest operatorem porównania powłoki do porównywania liczb całkowitych. Aby porównać ciągi, musisz użyć =.

codaddict
źródło
5

-eqjest matematycznym operatorem porównania. Nigdy nie używałem go do porównywania ciągów, polegania na ==i !=do porównań .

if [ 'XYZ' == 'ABC' ]; then   # Double equal to will work in Linux but not on HPUX boxes it should be if [ 'XYZ' = 'ABC' ] which will work on both
  echo "Match"
else
  echo "No Match"
fi
Jason
źródło
18
Zauważ, że operator ==nie działa na każdej powłoce. =jest prawidłowym operatorem do porównywania ciągów, a ==czasami jest synonimem.
Omer Dagan
3

Spośród 4 powłok, które przetestowałem, ABC -eq XYZwe testwbudowanej funkcji zshi ksh. Wyrażenie ma wartość false under /usr/bin/testi wbudowane dla dashi bash. W kshi zsh, łańcuchy są konwertowane na wartości liczbowe i są równe, ponieważ oba są równe 0. IMO, zachowanie poleceń wbudowanych dla kshi zshjest niepoprawne, ale specyfikacja dla testjest w tym przypadku niejednoznaczna.

William Pursell
źródło
1
Dzięki za test. Dlatego popularna jest powłoka Bourne'a.
Kemin Zhou
zsh wyraźnie wyświetla : wyrażenie całkowite oczekiwane po użyciu [ lub wbudowanego testu . Może wymuszasz [[], co ocenia oba jako 0, ponieważ łańcuchy nie są znaczącymi liczbami całkowitymi.
code933k
@ code933k Która wersja? Nie zdziwiłbym się, gdyby zachowanie się zmieniło.
William Pursell
@WilliamPursell zsh 5.7.1
code933k