Из любопытства, при выполнении сравнения переменных bash (его значение является integer
) можно проверить его по некоторому предопределенному значению, объявленному как int
или как string
.
Пример скрипта :
#!/bin/bash
f1()
{
[ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}
f2()
{
[[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}
f1 $1
f2 $1
Выход :
$ ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int
а также
$ ./param.sh blah
$
Обе функции ведут себя одинаково, и поэтому мне интересно, есть ли предпочтительный способ проверки целочисленной переменной? Я бы пошел на проверку int
против, так int
как это более строгое, но мне интересно, есть ли какие-либо недостатки сделать это string
?
В этом случае f2()
также более строгое сравнение, т. Е. Передача десятичного значения сломает его, в то время как f1()
это не вызовет проблем.
Ответы:
Да, много различий. Например,
=
проверяет точное равенство строк, но-eq
арифметически оценивает оба выражения перед проверкой на равенство:Кроме того, пустая строка численно равна нулю:
И совсем другой класс различий появляется, когда вы вводите операторы сравнения - например, в сравнении с
<
vs-lt
:Это связано с тем, что строка «2» расположена в алфавитном порядке после строки «10» (поскольку 1 стоит перед 2), но число «2» численно меньше числа «10».
источник
(( ... ))
для числовых операций.(( " 1 " == 1 )) && echo yes || echo no
Результатыyes
Сравнение целых и строк становится наиболее значимым, когда вы сравниваете больше или меньше чем:
Первый сбой, потому что 9 идет после 11, когда отсортированы лексикографически.
Обратите внимание, что использование кавычек не определяет, сравниваете ли вы строки или числа, оператор делает. Вы можете добавить или удалить цитаты выше, это не имеет никакого значения. Bash ловит неопределенные переменные в двойных скобках, поэтому кавычки не нужны. Использование кавычек с одинарными скобками для числовых тестов не спасет вас, поскольку:
В любом случае это ошибка («требуется целочисленное выражение»). Кавычки - эффективная гарантия сравнения строк в одинарных скобках:
Обратите внимание, в двойных скобках, но не
""
будет .-eq 0
== 0
источник
[[
модуль достаточно умен, чтобы помнить, где находятся переменные, и он не будет одурачен пустыми переменными. Одиночные скобки ([
) не имеют этой функции и требуют кавычек.[[ -lt 11 ]]
это ошибка, ноnothing=; [[ $nothing -lt 11 ]]
это не так. Я немного переработал последний абзац.В дополнение к тому, что было сказано.
Сравнение на равенство выполняется быстрее с числами, хотя в сценариях оболочки редко требуется быстрый расчет.
источник
=
, так как использование также-eq
будет соответствовать «+123». Если вы хотите знать, «Если эта переменная при оценке в виде арифметического выражения сравнивается равной 123», вы можете использовать только-eq
. Единственный раз, когда я могу увидеть, где программисту было бы все равно, какое определение равенства использовалось, это когда он знает, что содержимое переменной заранее ограничено определенным шаблоном.b=234
) соответствует этому шаблону - вы знаете, что это не +234 или «234» или «233 + 1», так как вы сами его присвоили, так что вы знаете, что сравнение его как строки и числа одинаково допустимо. Но сценарий OP, так как он принимает входные данные в качестве аргумента командной строки, не имеет такого ограничения - рассмотрите возможность назвать его как./param.sh 0+1
или./param.sh " 1"