쉘 스크립트를 사용하여 cmake가 3.13.4보다 크거나 작은지 확인하는 방법

쉘 스크립트를 사용하여 cmake가 3.13.4보다 크거나 작은지 확인하는 방법

내 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

-ltand 연산자는 -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

관련 정보