Bash: двойное равен vs -eq

47

Я делаю целочисленное сравнение в bash (пытаясь увидеть, работает ли пользователь от имени пользователя root), и я нашел два разных способа сделать это:

Двойной равно:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Я понимаю, что в bash нет> = или <=, только -ge и -le, так почему же есть a, ==если есть -eq?

Есть ли разница в том, как он сравнивает обе стороны?

beatgammit
источник
3
Обратите внимание, что пробелы в скобках обязательны:, [ $UID -eq 0 ]не [ $UID -eq 0].
Жиль "ТАК - перестань быть злым"

Ответы:

51

==является bash-специфическим псевдонимом =, который выполняет строку (лексическое) сравнение вместо -eqчислового сравнения. (Это от Perl: операторы в стиле слова являются числовыми, а символические - лексическими).

geekosaur
источник
Означает ли это, что если обе стороны являются целыми числами, он преобразует обе стороны в строки, а затем сравнивает их?
ритммит
5
Точнее, все наоборот: все является строкой, -eqговорит bashо том, что нужно интерпретировать строки как целые числа ( 0без предупреждения, если строка не числовая).
geekosaur
11
@tjameson Чтобы привести пример: [ 01 -eq 1 ]но [ 01 != 1 ].
Жиль "ТАК - перестань быть злым"
3
Следует отметить , что в то время ==как [оператор не является стандартным и не должен быть использован, это не Баш конкретного . Он был введен ksh и также поддерживается zsh (хотя первый =должен быть заключен в кавычки), yash и [утилитой GNU (и любыми такими утилитами, реализованными как скрипты ksh в некоторых системах), по крайней мере).
Стефан Шазелас
@geekosaur Я получаю предупреждение от bash v4.3.42, если моя строка не числовая: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: hello: ожидается целочисленное выражение
Эндрю Бейнбридж
13

Чтобы уточнить ответ боллована ...

Нет оператора сравнения >=или <=для строк. Но вы можете использовать их с ((...))арифметической командой для сравнения целых чисел.

Вы также можете использовать другие операторы сравнения строк ( ==, !=, <, >, но не =) для сравнения целых чисел , если вы используете их внутри ((...)).

Примеры

  • И то, [[ 01 -eq 1 ]]и другое (( 01 == 1 ))делают целочисленные сравнения. Оба верны.
  • Обе [[ 01 == 1 ]]и [ 01 = 1 ]строки сравнения. Оба ложные.
  • Оба (( 01 -eq 1 ))и (( 01 = 1 ))вернут ошибку.

Примечание. Синтаксис [[...]]с двойными скобками и синтаксис с двойными скобками ((...))поддерживаются не всеми оболочками.

toxalot
источник
1
Обратите внимание, что (за исключением mksh/ zsh(кроме режима POSIX (хотя это не функция POSIX))), (( 010 == 10 ))вернет false, потому 010что будет рассматриваться как восьмеричное число (8 в десятичном виде).
Стефан Шазелас
Обратите внимание , что в то время как большинство test/ [реализации не имеют >=/ <=операторы ( yash«S [имеет хотя), exprесть такие операторы, хотя он будет делать арифметическое сравнение , если аргументы признаются в качестве числа ( expr 01 '>=' 1возвращает значение ИСТИНА, expr X01 '>=' X1возвращается FALSE).
Стефан Шазелас
7

Если вы хотите сделать целочисленное сравнение, вам лучше использовать (()), где вы также можете использовать> = и т. Д.

Пример:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
bollovan
источник
Или (( UID == 0 ))или (( ! UID ))для этого имеет значение. Обратите внимание, что ((...))это нестандартно ( kshфункция также поддерживается bashи zshс вариациями).
Стефан Шазелас