自更新 bash 脚本,如果有任何更新,则先使用 Git 继续

自更新 bash 脚本,如果有任何更新,则先使用 Git 继续

我正在尝试为我添加能力ArchLinux 安装程序脚本检查它是否是最新的,而不是根据它匹配(或不匹配)gitlab 上的版本号。运行安装程序(以及所有编号的脚本文件)的主要脚本是脚本aalis.sh,它基本上一起运行其他文件。版本编号类似于1.2.3(major.minor.patch)。

基本上,每当我对脚本进行任何更改时,我都会更改脚本的 gitlab 版本号;我希望脚本本身能够检测到它的版本号与 github 上的版本号不匹配(对于有人拥有过时版本的脚本并尝试运行它的情况);并使用自动更新自身,git fetch origin master然后使用更新的内容重新运行自身。

答案1

在更新脚本之前将所有内容放在函数内。这可确保在替换脚本内容之前加载所有代码。

function some_function {
    ...
}

function main {
    ...
}

main "$@"

如果您可以将您的版本分离到另一个文件中,例如version.sh.那样的话就更加安全了。

答案2

我想到了!我找到了这个从脚本的在线存储库检索文件的答案,使用curl命令并更改URL以简单地检索VERSION.txt文件(该文件仅包含版本号,例如2.4.0并找到这个回答实际版本比较功能。合并两个答案后(并更改脚本的输出test_compare_versions,我的结果是这样的

# Answer from https://stackoverflow.com/a/49351294/17812185 by Maxxim
# Compare two version strings [$1: version string 1 (v1), $2: version string 2 (v2)]
# Return values:
#   0: v1 == v2
#   1: v1 > v2
#   2: v1 < v2
# Based on: https://stackoverflow.com/a/4025065 by Dennis Williamson
function compare_versions() {

    # Trivial v1 == v2 test based on string comparison
    [[ "$1" == "$2" ]] && return 0

    # Local variables
    local regex="^(.*)-r([0-9]*)$" va1=() vr1=0 va2=() vr2=0 len i IFS="."

    # Split version strings into arrays, extract trailing revisions
    if [[ "$1" =~ ${regex} ]]; then
        va1=(${BASH_REMATCH[1]})
        [[ -n "${BASH_REMATCH[2]}" ]] && vr1=${BASH_REMATCH[2]}
    else
        va1=($1)
    fi
    if [[ "$2" =~ ${regex} ]]; then
        va2=(${BASH_REMATCH[1]})
        [[ -n "${BASH_REMATCH[2]}" ]] && vr2=${BASH_REMATCH[2]}
    else
        va2=($2)
    fi

    # Bring va1 and va2 to same length by filling empty fields with zeros
    (( ${#va1[@]} > ${#va2[@]} )) && len=${#va1[@]} || len=${#va2[@]}
    for ((i=0; i < len; ++i)); do
        [[ -z "${va1[i]}" ]] && va1[i]="0"
        [[ -z "${va2[i]}" ]] && va2[i]="0"
    done

    # Append revisions, increment length
    va1+=($vr1)
    va2+=($vr2)
    len=$((len+1))

    # *** DEBUG ***
    echo "TEST: '${va1[@]} (?) ${va2[@]}'"

    # Compare version elements, check if v1 > v2 or v1 < v2
    for ((i=0; i < len; ++i)); do
        if (( 10#${va1[i]} > 10#${va2[i]} )); then
            return 1
        elif (( 10#${va1[i]} < 10#${va2[i]} )); then
            return 2
        fi
    done

    # All elements are equal, thus v1 == v2
    return 0
}

# Test compare_versions [$1: version string 1, $2: version string 2, $3: expected result]
function test_compare_versions() {
    compare_versions "$1" "$2"
    case $? in
        0) op="==" ;;
        1) op=">" ;;
        2) op="<" ;;
    esac

    if [[ "$op" == "==" ]]; then
        output ${LIGHT_GREEN} "The script is update to date!"
    elif [[ "$op" == "<" ]]; then
        output ${RED} "The script is out of date!!"
    elif [[ "$op" == ">" ]]; then
        output ${YELLOW} "The script is ahead of the release version, so this must be a release canidate or a beta build!"
    else
        banner ${RED} "SOMETHING HAS GONE WRONG, PLEASE REPORT THIS ERROR TO THE PROJECT'S GITLAB"
    fi

}


VERSION=1.2.0
ONLINE_VERSION=$(curl -s https://gitlab.com/NovaViper/testing-for-aalis-version-checker/-/raw/main/VERSION.txt)
test_compare_versions $VERSION $ONLINE_VERSION

相关内容