bash معنى باش مقارنة أرقام الإصدار




git bash (6)

يا رفاق لدي هذا البرنامج النصي الذي يجب التأكد من أن المستخدمين الحاليين نسخة فب بين مجموعة معينة، على الرغم من أنه ينبغي أن تعمل، هناك خلل في مكان ما أن يجعلها تعتقد أن الإصدار هو خارج النطاق، يمكن لشخص أن نلقي نظرة و قل لي ما يمكنني القيام به لإصلاحه؟

function version { echo "[email protected]" | 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

الحل التالي يجب أن يعالج بدقة أكبر حاجتك الدقيقة. يمكن استخدامه لاختبار ما إذا كانت سلسلة الإصدار CURRENT تقع بين MIN و MAX . أفترض أن MIN و MAX هما MAX مقبولان (أي MIN <= CURRENT <= MAX بدلا من MIN < CURRENT < MAX ).

# Usage: version MIN CURRENT MAX
version(){
    local h t v

    [[ $2 = "$1" || $2 = "$3" ]] && return 0

    v=$(printf '%s\n' "[email protected]" | sort -V)
    h=$(head -n1 <<<"$v")
    t=$(tail -n1 <<<"$v")

    [[ $2 != "$h" && $2 != "$t" ]]
}

فمثلا...

if ! version 5.2.13 "$phpver" 5.3.15; then
    echo "PHP Version $phpver must be between 5.2.13 - 5.3.15"
    exit
fi

dpkg --compare-versions <version> <relation> <version> dpkg --compare-versions "0.0.4" "gt" "0.0.3" if [ $? -eq "0" ]; then echo "YES"; else echo "NO"; fi dpkg --compare-versions <version> <relation> <version> على سبيل المثال: dpkg --compare-versions "0.0.4" "gt" "0.0.3" if [ $? -eq "0" ]; then echo "YES"; else echo "NO"; fi dpkg --compare-versions "0.0.4" "gt" "0.0.3" if [ $? -eq "0" ]; then echo "YES"; else echo "NO"; 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

أو تفعل كل شيء في أوك أو بعض أداة أخرى. هو يصرخ لبعض التحسين. يبدو أيضا أنك لا تنتج أرقام إما، لذلك يكون لديك تصميم غريب جدا. عادة يتم ضرب سوبسترينغس الإصدار في 1000 ثم كل لخص للحصول على العددية واحدة قابلة للمقارنة.


في ما يلي حل آخر:

  • لا تشغيل أي أمر خارجي بصرف النظر عن tr
  • لا يوجد لديه قيود على عدد من أجزاء في سلسلة الإصدار
  • يمكن مقارنة سلاسل الإصدار مع عدد مختلف من أجزاء

لاحظ أنه رمز باش باستخدام متغيرات الصفيف.

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
}

ترجع الدالة:

  • 0 إذا كانت الإصدارات متساوية (راجع للشغل: 1.2 == 1.2.0)
  • 1 إذا كان الإصدار 1 هو أكبر / أحدث
  • 2 إذا كان الإصدار الثاني هو أكبر / أحدث

ومع ذلك # 1 - أنه يتطلب وظيفة إضافية واحدة (ولكن min قابلة للاستخدام تماما أن يكون على أي حال):

min()
{
    local m="$1"
    for n in "[email protected]"
    do
        [ "$n" -lt "$m" ] && m="$n"
    done
    echo "$m"
}

ومع ذلك # 2 - فإنه لا يمكن مقارنة سلاسل الإصدار مع أجزاء ألفا رقمية (على الرغم من أن ذلك لن يكون من الصعب إضافة، في الواقع).


وإليك كيفية مقارنة الإصدارات.

باستخدام sort -V :

function version_gt() { test "$(printf '%s\n' "[email protected]" | sort -V | head -n 1)" != "$1"; }

مثال الاستخدام:

first_version=5.100.2
second_version=5.1.2
if version_gt $first_version $second_version; then
     echo "$first_version is greater than $second_version !"
fi

طليعة:

  • طريقة صلبة لمقارنة سلاسل نسخة يتوهم:
    • دعم أي طول من الأجزاء الفرعية (أي: 1.3alpha.2.dev2> 1.1؟)
    • دعم نوع ألفا-بيتيكال (أي: 1.alpha <1.beta2)
    • دعم إصدار كبير الحجم (أي: 1.10003939209329320932> 1.2039209378273789273؟)
  • يمكن تعديلها بسهولة لدعم الحجج n. (الأوراق كممارسة؛))
    • عادة مفيدة جدا مع 3 وسيطات: (أي: 1.2 <my_version <2.7)

سلبيات:

  • يستخدم الكثير من المكالمات المختلفة لبرامج مختلفة. لذلك ليس من الكفاءة.
  • يستخدم نسخة حديثة جدا من sort وأنه قد لا تكون متاحة على النظام الخاص بك. (تحقق مع man sort )

دون sort -V :

## each separate version number must be less than 3 digit wide !
function version { echo "[email protected]" | gawk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }

مثال الاستخدام:

first_version=5.100.2
second_version=5.1.2
if [ "$(version "$first_version")" -gt "$(version "$second_version")" ]; then
     echo "$first_version is greater than $second_version !"
fi

طليعة:

  • حل أسرع لأنه يدعو فقط 1 سوبروسيس
  • حل أكثر توافقا.

سلبيات:

  • محددة تماما، يجب أن سلسلة الإصدار:
    • يكون الإصدار مع 1 أو 2 أو 3 أجزاء فقط. (باستثناء "2.1.3.1")
    • يجب أن تكون كل جزء عدديا فقط (باستثناء "3.1a")
    • كل جزء لا يمكن أن يكون أكبر من 999 (يستبعد '1.20140417')

تعليقات حول النص البرمجي:

لا أستطيع أن أرى كيف يمكن أن تعمل:

  • كما ورد في تعليق > و < هي شخصية قذيفة خاصة جدا ويجب استبدالها من قبل -gt و -lt
  • حتى إذا قمت باستبدال الأحرف، لا يمكنك مقارنة أرقام الإصدار كما لو أنها حيث الأعداد الصحيحة أو تعويم. على سبيل المثال، على نظام بلدي، إصدار فب هو 5.5.9-1ubuntu4 .

ولكن version() مكتوبة بذكاء تماما بالفعل ويمكن أن تساعدك من خلال التحايل على المسألة الكلاسيكية أن الفرز أبجديا الأرقام لن فرز الأرقام عدديا (أبجديا 1 <11 <2، وهو خطأ عدديا). ولكن كن حذرا: لا يتم دعم أعداد كبيرة بشكل تعسفي من قبل باش (في محاولة للحفاظ على أقل من 32 بت إذا كنت تهدف إلى التوافق مع أنظمة 32bits، بحيث تكون 9 أرقام طويلة أرقام). لذلك قمت بتعديل التعليمات البرمجية (في الطريقة الثانية لا باستخدام sort -V ) لإجبار 3 أرقام فقط لكل جزء من سلسلة الإصدار.

إديت : تطبيقphk التحسن، كما هو بشكل ملحوظ كليفرر وإزالة مكالمة فرعية في الإصدار الأول باستخدام sort . شكر.


إذا كنت على باش 3 مع نسخة قديمة من sort (لوكين في لك ماك ...)، ثم قمت بإنشاء البرنامج النصي المساعد التالي يمكنك مصدر في (يمكن أيضا أن يتم تشغيل كأمر):

https://github.com/unicorn-fail/version_compare





shell