Сравните целое число в bash, ожидается унарный оператор - PullRequest
132 голосов
/ 03 января 2009

Следующий код дает

[: -ge: ожидается унарный оператор

когда

i=0

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

почему

Ответы [ 4 ]

283 голосов
/ 03 марта 2009

Ваша проблема возникает из-за того, что $i имеет пустое значение, когда ваше утверждение не выполнено. Всегда заключайте в кавычки ваши переменные при выполнении сравнений, если есть малейшая вероятность того, что одна из них может быть пустой, например ::10000 *

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

Это из-за того, как оболочка обрабатывает переменные. Предположим, оригинальный пример

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

Первое, что делает оболочка при выполнении этой конкретной строки кода, это подставляет значение $i, как это сделала бы функция search & replace вашего любимого редактора. Итак, предположим, что $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 - это куча пробелов, то это не считается как undefined , оно не будет заменено на 0, и вы снова столкнетесь с проблемой.

Пожалуйста, прочитайте это , когда у вас есть время. Многие воспринимают оболочку как черный ящик, но работают с очень немногими и очень простыми правилами - как только вы узнаете, что это за правила (одним из них является то, как переменные работают в оболочке, как описано выше), оболочка будет у тебя больше нет секретов.

6 голосов
/ 04 января 2013

Мне нужно добавить свои 5 центов. Я вижу, что все используют [ или [[, но стоит отметить, что они не являются частью синтаксиса if.

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

((...)) - арифметическая команда, которая возвращает состояние выхода 0, если выражение ненулевое или 1, если выражение равно нулю. Также используется в качестве синонима «let», если требуются побочные эффекты (назначения).

См .: Арифметическое выражение

6 голосов
/ 03 января 2009

Судя по сообщению об ошибке, значением i была пустая строка, когда вы ее выполняли, а не 0.

2 голосов
/ 03 января 2009

Ваш кусок скрипта работает просто замечательно. Вы уверены, что ничего не назначаете перед if для i?

Распространенной ошибкой также является отсутствие пробелов после и перед квадратными скобками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...