私のcmakeバージョンが3.13.4以上であることを確認したいと思います。それ以外の場合は、3.13.4より小さい場合は最新バージョンをビルドしてください。ここにスクリプトがあります。
#!/bin/sh
RESULT=$(cmake --version)
if [ "$RESULT" -ge 3.13.4 ]; then
echo "you are using the latest version of cmake"
elif [ "$RESULT" -lt 3.13.4 ]; then
cd /home/builduser
mkdir cmake
cd cmake
apt install wget libssl-dev
wget https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2.tar.gz
tar -xf cmake-3.22.2.tar.gz
cd cmake-3.22.2
./configure
make install
cd /home/builduser
rm -rf cmake
fi
答え1
GNUソートにはバージョンソートオプションがあります-V
。
cmp=3.13.4
ver=$(cmake --version | head -1 | cut -f3 -d" ")
mapfile -t sorted < <(printf "%s\n" "$ver" "$cmp" | sort -V)
if [[ ${sorted[0]} == "$cmp" ]]; then
echo "cmake version $ver >= $cmp"
fi
答え2
これを行う古典的な方法は、次のものを使用することですcase
。
case $(cmake --version | awk '/cmake version/ {print $3}') in
[012].*|3.?|3.?.*|3.1[012]|3.1[012].*|3.13|3.13.[0123])
echo Too old
# Download and build
;;
*)
echo OK;;
esac
答え3
-lt
and 演算子は-gt
数値比較にのみ使用できます。 「3.13.4」は数字ではなくバージョン文字列です。を使用すると仮定すると、次の関数をbash
作成できます。version_comp
version_comp() {
local min_version
local have_version
[[ "$1" == "$2" ]] && return 0
mapfile -t -d. min_version <<<"$1"
mapfile -t -d. have_version <<<"$2"
for ((i=0; i<${#min_version[*]}; i++)); do
if (( have_version[i] > min_version[i] )); then
return 0
elif (( have_version[i] < min_version[i] )); then
return 1
fi
done
return 0
}
バージョン文字列を配列に分割することで、mapfile
各コンポーネントを数値的にテストできます。
今テストしてみましょう:
target=3.13.3
# Test versions greater than or equal to target
while read -r value; do
if version_comp "$target" "$value"; then
echo "PASSED: $value >= $target"
fi
done << EOF
3.14.4
3.15.0
4
4.0.0
4.1.2
10
EOF
echo
# Test versions less than target
while read -r value; do
if ! version_comp "$target" "$value"; then
echo "PASSED: $value < $target"
fi
done << EOF
2
1.2.3
3.14.2
0
EOF
次を生成します。
PASSED: 3.14.4 >= 3.13.3
PASSED: 3.15.0 >= 3.13.3
PASSED: 4 >= 3.13.3
PASSED: 4.0.0 >= 3.13.3
PASSED: 4.1.2 >= 3.13.3
PASSED: 10 >= 3.13.3
PASSED: 2 < 3.13.3
PASSED: 1.2.3 < 3.13.3
PASSED: 0 < 3.13.3
答え4
きれいではありませんが、バージョン番号をさまざまな部分に分割して各部分を比較する必要があると思います。たとえば、3.9 < 3.14 なので、一般的な算術は使用できません。
おそらくこれよりもっときれいなものがあるでしょう。しかし、これが私が思いついたものです:
#!/usr/bin/env bash
# get version and strip any extra junk
result="$(cmake --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')"
# major version number is what precedes first period
major="${result%%.*}"
# take what's left
remainder="${result#*.}"
# what precedes first period in the remainder is the minor version num.
minor="${remainder%.*}"
# revision is what's left after that
revision="${remainder#*.}"
# either the major must be higher,
# or it must be the same and the minor must be higher
# or both must be the same and the release must be high enough
if [ "$major" -gt 3 ] ||
( [ "$major" -eq 3 ] &&
( [ "$minor" -gt 14 ] ||
( [ "$minor" -eq 14 ] && [ "$release" -ge 4 ] ))) ; then
echo "you are using a version of cmake >= 3.14.4"
# version is >= 3.14.4; do stuff
else
echo "you are using an older version of cmake"
# do older version stuff
fi
別のアプローチは、比較を実行する再帰関数を書くことです。少し長めですが、よりきれいで柔軟です。
#!/usr/bin/env bash
version_equal_or_greater() {
# read arguments
a="$1"
b="$2"
# if they're identical return true (return code 0)
if [ "$a" == "$b" ] ; then
return 0
fi
# read numbers before first .
amajor="${a%%.*}"
bmajor="${b%%.*}"
# if first is greater return true (return code 0)
if [ "$amajor" -gt "$bmajor" ] ; then
return 0
fi
# if first is less return false (return code 1)
if [ "$amajor" -lt "$bmajor" ] ; then
return 1
fi
# should be the same; compare remainders
version_equal_or_greater "${a#*.}" "${b#*.}"
}
result="$(cmake --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')"
if version_equal_or_greater "$result" "3.14.4" ; then
echo "you are using a version of cmake >= 3.14.4"
# version is >= 3.14.4; do stuff
else
echo "you are using an older version of cmake"
fi