Порівняйте ціле число в bash, очікується одинарний оператор


137

Наступний код дає

[: -ge: очікується одинарний оператор

коли

i=0

if [ $i -ge 2 ]
then
    #some code
fi

чому?

Відповіді:


295

Ваша проблема виникає через те, що $iмає порожнє значення, коли ваше повідомлення не працює. Завжди цитуйте свої змінні під час порівняння, якщо є найменший шанс, що одна з них може бути порожньою, наприклад:

if [ "$i" -ge 2 ] ; then
  ...
fi

Це через те, як оболонка поводиться зі змінними. Припустимо оригінальний приклад,

if [ $i -ge 2 ] ; then ...

Перше, що робить оболонка під час виконання конкретного рядка коду, замінює значення $i, як і функція пошуку та заміни улюбленого редактора . Тож припустимо, що $iце порожнє або, ще більш наочно, припустимо, що $iце купа пробілів! Оболонку замінить $iнаступним чином:

if [     -ge 2 ] ; then ...

Тепер, коли заміна змінних зроблена, оболонка проходить із порівнянням і .... не вдається, тому що зліва від неї не видно нічого зрозумілого -gt. Однак, цитуючи $i:

if [ "$i" -ge 2 ] ; then ...

стає:

if [ "    " -ge 2 ] ; then ...

Оболонка тепер бачить подвійні лапки і знає, що ви насправді порівнюєте чотири пробіли до 2 і будете пропускати if.

У вас також є можливість вказати значення за замовчуванням для, $iякщо $iвоно порожнє, як описано нижче:

if [ "${i:-0}" -ge 2 ] ; then ...

Це замінить значення 0, а $iне $iє невизначеним. Я все ще підтримую котирування, тому що, знову ж таки, якщо $iкупа пробілів, то вона не вважається невизначеною , вона не буде замінена на 0, і ви знову зіткнетеся з проблемою.

Будь ласка, прочитайте це, коли у вас є час. Оболонка трактується як чорна скринька багатьма, але вона оперує дуже мало і дуже простими правилами - як тільки ви дізнаєтеся, що це за правила (одним із них є те, як змінні працюють в оболонці, як пояснено вище) оболонка буде більше не має для вас секретів.


7
Цитування змінної призведе до появи нової помилки, як очікується ціле вираження
Нестор

@ Нестор неправильно , котирування змінної НЕ спричинить нову помилку, як очікуване ціле число, якщо змінна є числовою; забезпечуючи НЕ числове значення змінної, будь то цитироваться чи ні, буде приводити до зазначеної помилки.
vladr

6

Якщо судити з повідомлення про помилку, значення i була порожньою рядком, коли ви її виконували, а не 0.


6

Мені потрібно додати свої 5 центів. Я бачу, що всі користуються [або [[, але варто зазначити, що вони не є частиною синтаксису if.

Для арифметичних порівнянь використовуйте ((...))замість цього.

((...)) - це арифметична команда, яка повертає статус виходу 0, якщо вираз ненульовий, або 1, якщо вираз дорівнює нулю. Також використовується як синонім "нехай", якщо потрібні побічні ефекти (призначення).

Див.: Арифметична експресія


2

Ваш сценарій працює чудово. Ви впевнені, що не присвоюєте нічого іншого перед "if" на "i"?

Поширена помилка - також не залишати місця після квадратних дужок та перед ними.

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