Сравните целое число в bash, ожидаемый унарный оператор

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

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

когда

i=0

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

Зачем?

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

Смотрите: ArithmeticExpression

Ответ 4

Ваша часть script работает просто отлично. Вы уверены, что не назначаете что-либо еще до if, чтобы "i"?

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