Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Bash比较PHP版本号?_Bash_Shell - Fatal编程技术网

使用Bash比较PHP版本号?

使用Bash比较PHP版本号?,bash,shell,Bash,Shell,我有一个脚本,可以确保用户当前的PHP版本在一定的范围内,虽然它应该可以工作,但是有一个bug让它认为版本超出了范围,有人可以看一下并告诉我如何修复它吗 function version { echo "$@" | gawk -F. '{ printf("%d.%d.%d\n", $1,$2,$3); }'; } phpver=`php -v |grep -Eow '^PHP [^ ]+' |gawk '{ print $2 }'` if [ $(version $phpver) >

我有一个脚本,可以确保用户当前的PHP版本在一定的范围内,虽然它应该可以工作,但是有一个bug让它认为版本超出了范围,有人可以看一下并告诉我如何修复它吗

function version { echo "$@" | gawk -F. '{ printf("%d.%d.%d\n", $1,$2,$3); }'; }

phpver=`php -v |grep -Eow '^PHP [^ ]+' |gawk '{ print $2 }'`

if [ $(version $phpver) > $(version 5.2.13) ] || [ $(version $phpver) < $(version 5.2.13) ]; then
  echo "PHP Version $phpver must be between 5.2.13 - 5.3.15"
  exit
fi
函数版本{echo“$@”| gawk-F.{printf(“%d.%d.%d\n”),$1,$2,$3);}
phpver=`php-v | grep-Eow'^php[^]+'| gawk'{print$2}'`
如果[$(版本$phpver)>$(版本5.2.13)]|[$(版本$phpver)<$(版本5.2.13)];然后
echo“PHP版本$phpver必须介于5.2.13和5.3.15之间”
出口
fi

它正在进行词法比较。使用其中一种:

if [ $(version $phpver) -gt $(version 5.2.13) ] || [ $(version $phpver) -lt $(version 5.2.13) ]; then
if [[ $(version $phpver) > $(version 5.2.13) ]] || [[ $(version $phpver) < $(version 5.2.13) ]]; then
if (( $(version $phpver) > $(version 5.2.13) )) || (( $(version $phpver) < $(version 5.2.13) )); then
if[$(版本$phpver)-gt$(版本5.2.13)]||[$(版本$phpver)-lt$(版本5.2.13)];然后
如果[[$(版本$phpver)>$(版本5.2.13)]|[[$(版本$phpver)<$(版本5.2.13)];然后
如果($(版本$phpver)>$(版本5.2.13))| |($(版本$phpver)<$(版本5.2.13));然后

或者在awk或其他工具中完成这一切。它迫切需要一些优化。看起来你也没有生成数字,所以你有一个非常奇怪的设计。通常情况下,版本子字符串乘以1000,然后全部相加得到一个可比较的标量。

下面介绍如何比较版本

使用
排序-V

function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
## each separate version number must be less than 3 digit wide !
function version { echo "$@" | gawk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }
用法示例:

赞成者:

  • 比较奇特版本字符串的可靠方法:
    • 支持任何长度的子零件(即:1.3alpha.2.dev2>1.1?)
    • 支持alpha-betical排序(即:1.alpha<1.beta2)
    • 支持大尺寸版本(即:1.10003939209329320932>1.20392093778273789273?)
  • 可以轻松修改以支持n个参数。(作为练习离开;)
    • 通常有3个参数非常有用:(即:1.2
缺点:

  • 对不同的程序使用大量不同的调用。所以它没有那么有效
  • 使用了最新版本的
    sort
    ,您的计算机上可能没有该版本 系统。(使用
    人工分拣检查
排序-V

function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
## each separate version number must be less than 3 digit wide !
function version { echo "$@" | gawk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }
用法示例:

赞成者:

  • 更快的解决方案,因为它只调用1个子流程
  • 更兼容的解决方案
缺点:

  • 非常具体,版本字符串必须:
    • 只有1、2或3个零件的版本。(不包括“2.1.3.1”)
    • 每个零件必须仅为数字(不包括“3.1a”)
    • 每个部分不能大于999(不包括“1.20140417”)
对脚本的评论:

function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
## each separate version number must be less than 3 digit wide !
function version { echo "$@" | gawk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }
我看不出它是如何工作的:


  • 如注释
    所述,以下解决方案应更准确地满足您的确切需求。它可用于测试当前版本字符串是否介于
    MIN
    MAX
    之间。我假设
    MIN
    MAX
    是可接受的版本号(即
    MIN如果您在Bash 3上使用较旧版本的
    sort
    (查看您的macOS…),那么我创建了以下帮助程序脚本,您可以从中获取(也可以作为命令运行):


    这里有另一个解决方案:

    • 除了
      tr
    • 对版本字符串中的部件数量没有限制
    • 可以比较具有不同部件数的版本字符串
    注意,它是使用数组变量的Bash代码

    compare_versions()
    {
        local v1=( $(echo "$1" | tr '.' ' ') )
        local v2=( $(echo "$2" | tr '.' ' ') )
        local len="$(max "${#v1[*]}" "${#v2[*]}")"
        for ((i=0; i<len; i++))
        do
            [ "${v1[i]:-0}" -gt "${v2[i]:-0}" ] && return 1
            [ "${v1[i]:-0}" -lt "${v2[i]:-0}" ] && return 2
        done
        return 0
    }
    

    但是#2——它无法将版本字符串与字母数字部分进行比较(尽管实际上这并不难添加)。

    测试PHP CLI版本的更安全的方法是使用PHP自己的函数

    !/bin/bash
    MIN_VERSION=“7.0.0”
    MAX_VERSION=“7.1.4”
    PHP_VERSION=`PHP-r'echo PHP_VERSION;'`
    函数版本\u比较(){
    比较_OP=$1;
    测试版=2美元;
    结果=$(php-r'echo version_compare(php_version,“${TEST_version}'”,“${compare_OP}'”)“TRUE”:“;”)
    测试-n“${RESULT}”;
    }
    如果(version_compare“”“${MAX_version}”);则
    echo“PHP版本${PHP_版本}必须介于${MIN_版本}-${MAX_版本}”之间;
    出口1;
    fi
    echo“PHP版本${PHP_Version}很好!”;
    
    有可能进行deb分配:

    dpkg --compare-versions <version> <relation> <version>
    

    我不久前为一个类似的问题编写了这个不雅观的函数。如果arg1小于或等于arg2,vers_limit将返回0,否则为非0:

    vers_limit()
    {
    VERNEW=$1
    VERLMT=$2
    
    CHKNEW=$VERNEW
    CHKLMT=$VERLMT
    
    PASSED=
    
    while :
    do
            PARTNEW=${CHKNEW%%.*}
            PARTLMT=${CHKLMT%%.*}
            if [[ $PARTNEW -lt $PARTLMT ]]
            then
                    PASSED=GOOD
                    break
            elif [[ $PARTNEW -gt $PARTLMT ]]
            then
                    PASSED=
                    break
            else
                    NXTNEW=${CHKNEW#*.}
                    if [[ $NXTNEW == $CHKNEW ]]
                    then
                            if [[ $NXTNEW == $CHKLMT ]]
                            then
                                    PASSED=GOOD
                                    break
                            else
                                    NXTNEW=0
                            fi
                    fi
                    NXTLMT=${CHKLMT#*.}
                    if [[ $NXTLMT == $CHKLMT ]]
                    then
                            NXTLMT=0
                    fi
            fi
            CHKNEW=$NXTNEW
            CHKLMT=$NXTLMT
    done
    test "$PASSED"
    }
    
    这并不像这里的其他一些解决方案那样紧凑,也没有提供三向状态(即更少、相等、更大),尽管我相信人们可以排序参数、解释通过/失败状态和/或调用两次以实现任何期望的结果。也就是说,vers_limit确实具有某些优点:

  • 不调用外部实用程序,如sort、awk、gawk、tr等

  • 处理任意大小的数字版本(最多为shell的 整数计算的限制)

  • 处理任意数量的“虚线”零件

  • < P> >代码> > VMIN ,<代码> VyMAX 和 VY-PHP版本号,如果代码不在中间,则进行测试。

    纯BASH 我找到了访问此页面的方法,因为我遇到了相同的问题。其他答案不能让我满意,因此我编写了此函数。
    只要两个版本中的句号相同,就可以正确比较版本。
    它对循环执行c风格,在版本字符串中从0到#的数字增量设置$i。
    对于每个#::
    如果new-old为neg,则我们知道第一个版本较新。
    如果是新旧版本,我们知道第一个版本较旧。
    如果new-old为0,则它是相同的,我们需要继续检查。
    在$1==$2版本完全相同的情况下,我们运行false来设置函数的退出状态

    newver=1.10.1
    安装版本=1.9.25
    #安装版本=1.11.25
    #安装版本=
    
    dpkg --compare-versions "0.0.4" "gt" "0.0.3"
    if [ $? -eq "0" ]; then echo "YES"; else echo "NO"; fi
    
    vers_limit()
    {
    VERNEW=$1
    VERLMT=$2
    
    CHKNEW=$VERNEW
    CHKLMT=$VERLMT
    
    PASSED=
    
    while :
    do
            PARTNEW=${CHKNEW%%.*}
            PARTLMT=${CHKLMT%%.*}
            if [[ $PARTNEW -lt $PARTLMT ]]
            then
                    PASSED=GOOD
                    break
            elif [[ $PARTNEW -gt $PARTLMT ]]
            then
                    PASSED=
                    break
            else
                    NXTNEW=${CHKNEW#*.}
                    if [[ $NXTNEW == $CHKNEW ]]
                    then
                            if [[ $NXTNEW == $CHKLMT ]]
                            then
                                    PASSED=GOOD
                                    break
                            else
                                    NXTNEW=0
                            fi
                    fi
                    NXTLMT=${CHKLMT#*.}
                    if [[ $NXTLMT == $CHKLMT ]]
                    then
                            NXTLMT=0
                    fi
            fi
            CHKNEW=$NXTNEW
            CHKLMT=$NXTLMT
    done
    test "$PASSED"
    }
    
    v_min="5.2.15"
    v_max="5.3.15"
    v_php="$(php -v | head -1 | awk '{print $2}')"
    
    [ ! "$v_php" = "$(echo -e "$v_php\n$v_min\n$v_max" | sort -V | head -2 | tail -1)" ] && {
      echo "PHP Version $v_php must be between $v_min - $v_max"
      exit
    }