Самый простой способ сделать это в Bash - использовать sort -V
.
Чтобы решить проблему сравнения строк версий в целом в bash, вот простая compare()
функция, которая принимает два аргумента a и b и возвращает true, если a <= b. А затем некоторые модульные тесты, показывающие его допустимость для различных входных данных версии Python: </p>
# test.sh
compare() {
local a=$1 ; local b=$2
[ "$( (echo "$a" ; echo "$b") | sort -V | head -1)" == "$a" ]
}
test22p1() {
compare "2.2p1" "3.0.0"
assertTrue "$?"
}
test214() {
compare "2.1.4" "3.0.0"
assertTrue "$?"
}
test300() {
compare "3.0.0" "3.0.0"
assertTrue "$?"
}
test372() {
compare "3.7.2" "3.0.0"
assertFalse "$?"
}
. shunit2
Выход:
▶ bash test.sh
test22p1
test214
test300
test372
Ran 4 tests.
OK
(Эти модульные тесты предполагают, что shunit2 установлен, конечно.)
О функции:
Он просто повторяет $a
, а затем $b
по двум отдельным линиям, соединяет трубы в sort -V
и берет голову. Если голова равна левой стороне, возвращается true; в противном случае, если он равен правой части, возвращается false.
В своем вопросе, который вы упомянули, вы действительно хотите знать, установлен ли Python 3 или выше, так что вы можете изменить его и получить что-то вроде этого:
python3_installed() {
local a b
a=$(python --version 2>&1 | perl -pe 's/python *//i') ; b=3
[ "$( (echo "$a" ; echo "$b") | sort -V | head -1)" == "$b" ]
}
Эта функция будет вычислять фактическую версию установленного Python, сравнивать ее с "3", используя sort -V
, и возвращать false, если не установлено 3 или выше.
Обратите внимание на использование Perl для поиска и замены регулярного выражения без учета регистра. (Не все sed имеют нечувствительную к регистру способность.)
Самое замечательное в этом - то, что вы можете иметь читаемый код при вызове, например:
if python3_installed ; then
# yes it is!
else
# ...
fi
Наконец, в соответствии с документами для sort -V
(из руководства BSD; POSIX не указывает опцию -V
, но большинство сортов, кажется, имеет ее):
`-V, --version-sort`
Сортировка номеров версий. Строки ввода обрабатываются как имена файлов в форме PREFIX VERSION SUFFIX, где SUFFIX соответствует регулярному выражению (.([A-Za-z~][A-Za-z0-9~]*)?)*
. Файлы сравниваются по их префиксам и версиям (начальные нули игнорируются в номерах версий, см. Пример ниже). Если входная строка не соответствует шаблону, то она сравнивается с помощью функции сравнения байтов. Все сравнения строк выполняются в локали C, настройка среды локали игнорируется.