Порівняйте рядок, використовуючи оболонку sh


197

Я використовую оболонку SH і намагаюся порівняти рядок зі значенням змінної, але ifумова завжди виконується до істини. Чому?

Ось деякий код:

Sourcesystem="ABC"

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

echo Sourcesystem Value is  $Sourcesystem ;

Навіть це не працює:

Sourcesystem="ABC"

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

echo Sourcesystem Value is  $Sourcesystem ;

По-друге, чи можемо ми зіставити це з NULL або порожнім рядком?


Спочатку в оболонці Борна вам не потрібно зайве ';' Під час тестового запуску сценарію в оболонці Борна умова if не відповідає дійсності. Спочатку видасть попередження: [: ABC: очікується цілочисельний вираз. Результат: "Система джерел не відповідає ABC". Як коментували інші, -eq використовується для цілочисельних порівнянь. Використовуйте один знак рівності для порівняння рядків у оболонці Борна (#! / Bin / sh). Перш за все ваша оболонка мала виправити вас.
Kemin Zhou

6
Голосування за відновлення. Процитовані дупки стосуються оболонки баша, а не анемічної оболонки sh, яка іноді є оболонкою Posix або тире.
jww

1
Погодились і так проголосували. shі bashмають ті самі відносини, що Cі C++. Незважаючи на те, що код, написаний для першого, дійсний для другого, відповіді для другого не можна довіряти, що він працює в першому.
btilly

Відповіді:


290

=Для порівняння рядків слід використовувати оператор:

Sourcesystem="ABC"

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

man testговорить, що ви використовуєте -zдля зіставлення порожніх рядків.


2
Не потрібно цитувати ABCабо XYZ.
закінчується

29
Якщо у вашій змінній можуть бути пробіли, тоді цитування необхідне.
Вільям Еверетт,

1
Налаштував приклад, щоб зробити цю частину зрозумілішою @WilliamEverett.
Per Lundberg


36

eq використовується для порівняння цілих чисел, замість цього використовується рівне '=', приклад:

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

Щасти


Примітка: якщо ви порівнюєте змінні, обов’язково використовуйте, "$VAR"а не просто$VAR
Шрідхар Сарнобат

22

У мене була така сама проблема, зробіть це

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

Зверніть увагу на пробіли. Важливо, щоб у цьому випадку ви використовували пробіли після та перед= знаком.

Перегляньте " Інші оператори порівняння ".


1
у Dockerfile: / bin / sh: 1: [: =: несподіваний оператор
holms

10

-eqє оператором порівняння оболонки для порівняння цілих чисел. Для порівняння рядків потрібно використовувати =.


5

-eqє математичним оператором порівняння. Я ніколи не використовував його для порівняння рядків, спираючись на ==і !=для порівняння.

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

18
Зверніть увагу, що оператор ==працює не з кожною оболонкою. =є правильним оператором для порівняння рядків, а ==іноді є синонімом.
Омер Даган

3

З 4 оболонок, які я протестував, ABC -eq XYZоцінює як справжні testвбудовані для zshі ksh. Вираз обчислюється як false під /usr/bin/testі вбудовані для dashі bash. У kshі zsh, рядки перетворюються в числові значення і рівні, оскільки вони обидва рівні 0. IMO, поведінка вбудованих kshі zshневірна, але специфікація для testцього неоднозначна.


1
Дякую за тестування. Тому панцир Борна популярний.
Kemin Zhou

zsh чітко виводить : цілочисельний вираз, очікуваний після використання [ або вбудованого тесту . Можливо, ви примушуєте [[ який оцінює як 0, оскільки рядки не є значущими цілими числами.
code933k

@ code933k Яка версія? Я б не здивувався, якщо поведінка змінилася.
Вільям Перселл,

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