শেল স্ক্রিপ্টে কোনও প্রোগ্রামের সংস্করণটি কীভাবে তুলনা করবেন?


14

মনে করুন আমি gccসিস্টেমে সর্বনিম্ন সংস্করণ ইনস্টল হয়েছে কিনা তা দেখতে সংস্করণটি তুলনা করতে চাই ।

gccসংস্করণটি পরীক্ষা করতে , আমি নিম্নলিখিতটি সম্পাদন করেছি

gcc --version | head -n1 | cut -d" " -f4

আউটপুট ছিল

4.8.5

সুতরাং, আমি ifএই সংস্করণটি অন্য কয়েকটি মানের বিপরীতে পরীক্ষা করতে একটি সাধারণ বিবৃতি লিখেছি

if [ "$(gcc --version | head -n1 | cut -d" " -f4)" -lt 5.0.0 ]; then
    echo "Less than 5.0.0"
else
    echo "Greater than 5.0.0"
fi

তবে এটি একটি ত্রুটি ছুড়ে ফেলে:

[: integer expression expected: 4.8.5

আমি আমার ভুল বুঝতে পেরেছিলাম যে আমি তুলনা করতে স্ট্রিংগুলি ব্যবহার করছিলাম এবং এর -ltজন্য পূর্ণসংখ্যার প্রয়োজন। সুতরাং, সংস্করণ তুলনা করার অন্য কোন উপায় আছে?


@ 123 কিছুই হয় না
অভিমন্যু সাহারান

1
সংস্করণ স্ট্রিংগুলির তুলনা করার জন্য বিভিন্ন পরামর্শের একটি গুচ্ছ সহ একটি স্ট্যাক ওভারফ্লো প্রশ্ন রয়েছে।
n.st

1
পাইপ ব্যবহার করা থেকে অনেক সহজ:gcc -dumpversion
ভিক্টর ল্যামোইন

উত্তর:


22

আমি জানি না এটি সুন্দর কিনা তবে এটি আমার জানা প্রতিটি সংস্করণ বিন্যাসের জন্য কাজ করছে।

#!/bin/bash
currentver="$(gcc -dumpversion)"
requiredver="5.0.0"
 if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then 
        echo "Greater than or equal to 5.0.0"
 else
        echo "Less than 5.0.0"
 fi

( দ্রষ্টব্য: ব্যবহারকারী 'ওয়াইল্ডকার্ড' এর আরও ভাল সংস্করণ: https://unix.stackexchange.com/users/135943/wildcard , অতিরিক্ত শর্ত সরানো হয়েছে)


3
প্রথমে আমি ভয়াবহ বলে ভেবেছিলাম এবং তারপরে আমি বুঝতে পেরেছিলাম যে শেল স্ক্রিপ্টিংয়ের সৌন্দর্যটি ঠিক এইভাবে অপব্যবহারকারী সরঞ্জামগুলিতে। +1
মনিকা সেলিলিওর

2
মুদ্রণ বিবৃতিতে '%' চিহ্ন থাকলে এটি বিরতি দেয়। printf "$requiredver\n$currentver"সঙ্গে ভাল প্রতিস্থাপন printf '%s\n' "$requiredver" "$currentver"
phk

1
-Vএকটি জিএনইউ এক্সটেনশন sort(1)এইভাবে এই সমাধানটি বহনযোগ্য নয়।
স্টিফ্যান্ট

1
sort -nসংখ্যা সংস্করণের ক্ষেত্রে একইভাবে কাজ করে works
রক্যালাইট

1
@ লুসিওআনড্রেসমার্টিনি, আমার সম্পাদনা সম্পর্কে আপনি কী ভাবেন তা দেখুন।
ওয়াইল্ডকার্ড

2

এখানে আমি ইউনিক্স কার্নেল সংস্করণগুলির তুলনা করার জন্য একটি সমাধান দিই। এবং এটি অন্যদের যেমন জিসিসির জন্য কাজ করা উচিত। আমি কেবল প্রথম 2 সংস্করণ নম্বরটির জন্য যত্ন নিই তবে আপনি যুক্তির আরও একটি স্তর যুক্ত করতে পারেন। এটি একটি লাইনার এবং আমি এটি বোঝার জন্য একাধিক লাইনে লিখেছি।

check_linux_version() {
    version_good=$(uname -r | awk 'BEGIN{ FS="."}; 
    { if ($1 < 4) { print "N"; } 
      else if ($1 == 4) { 
          if ($2 < 4) { print "N"; } 
          else { print "Y"; } 
      } 
      else { print "Y"; }
    }')

    #if [ "$current" \< "$expected" ]; then
    if [ "$version_good" = "N" ]; then
        current=$(uname -r)
        echo current linux version too low
        echo current Linux: $current
        echo required 4.4 minimum
        return 1
    fi
}

আপনি এটি পরিবর্তন করতে পারেন এবং এটি জিসিসি সংস্করণ পরীক্ষার জন্য ব্যবহার করতে পারেন।


+1 এটি অন্যান্য ইউনিক্সের মতো সামঞ্জস্যপূর্ণ? (আমার সমাধানটি নয়)
লুসিয়ানো অ্যান্ড্রেস মার্টিনি

1

আমরা একটি জিএনইউ মেকফাইলে প্রচুর সংস্করণ চেক করতাম। আমরা মেকফাইল সুবিধার মাধ্যমে শেল্ট আউট করেছি। আমাদের পুরানো বিন্টিলস এবং বগি সংকলকগুলি সনাক্ত করতে হয়েছিল এবং সেগুলি ফ্লাইতে সন্ধান করতে হয়েছিল।

আমরা যে প্যাটার্নটি ব্যবহার করেছি তা হ'ল:

#!/usr/bin/env bash

CC=$(command -v gcc)
GREP=$(command -v grep)

# Fixup CC and GREP as needed. It may be needed on AIX, BSDs, and Solaris
if [[ -f "/usr/gnu/bin/grep" ]]; then
    GREP="/usr/gnu/bin/grep"
elif [[ -f "/usr/linux/bin/grep" ]]; then
    GREP="/usr/linux/bin/grep"
elif [[ -f "/usr/xpg4/bin/grep" ]]; then
    GREP="/usr/xpg4/bin/grep"
fi

# Check compiler for GCC 4.8 or later
GCC48_OR_LATER=$("$CXX" -v 2>&1 | "$GREP" -i -c -E "gcc version (4\.[8-9]|[5-9]\.)")
if [[ "$GCC48_OR_LATER" -ne 0 ]];
then
   ...
fi

# Check assembler for GAS 2.19 or later
GAS219_OR_LATER=$("$CXX" -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | "$GREP" -c -E "GNU assembler version (2\.19|2\.[2-9]|[3-9])")
if [[ "$GAS219_OR_LATER" -ne 0 ]];
then
   ...
fi

নিস! এটি কাজ করে এবং প্রসারিত করা অত্যন্ত সহজ এবং খুব বহনযোগ্য!
ব্র্যাড পার্কস

1

সংক্ষিপ্ত সংস্করণ:

version_greater_equal()
{
    printf '%s\n%s\n' "$2" "$1" | sort -V -C
}

version_greater_equal "${gcc_version}" 8.2 || die "need 8.2 or above"

(1) এটি ইতিমধ্যে প্রদত্ত উত্তরের একটি সামান্য প্রকরণ। আপনি একটি ব্যাখ্যা যোগ করে মান যুক্ত করতে পারেন, যা এখনও পোস্ট করা হয়নি। (2)  printf '%s\n'যথেষ্ট ভাল; printfপ্রয়োজন অনুযায়ী ফর্ম্যাট স্ট্রিং পুনরাবৃত্তি করবে।
জি-ম্যান

আমি সাধারণত বিদ্যমান উত্তরগুলি সম্পাদনা করতে পছন্দ করি তবে সেগুলির অর্ধেক মুছে ফেলা মুশকিল: অন্যরা আমার কাছে যেখানে মান দেয় না সেখানে মান দেখতে পারে। ভার্জোজ ব্যাখ্যার জন্য একই। কমই বেশি.
মার্চ

আমি জানি যে printfফর্ম্যাট স্ট্রিংটি পুনরাবৃত্তি করেছে তবে আমি এর (বাক্সের অভাব) সিনট্যাক্সটি IMHO অস্পষ্ট; সুতরাং আমি কেবল তখনই এটি ব্যবহার করি = যখন আর্গুমেন্টের সংখ্যা বড় বা পরিবর্তনশীল হয়।
মার্চ

1
function version_compare () {
  function sub_ver () {
    local len=${#1}
    temp=${1%%"."*} && indexOf=`echo ${1%%"."*} | echo ${#temp}`
    echo -e "${1:0:indexOf}"
  }
  function cut_dot () {
    local offset=${#1}
    local length=${#2}
    echo -e "${2:((++offset)):length}"
  }
  if [ -z "$1" ] || [ -z "$2" ]; then
    echo "=" && exit 0
  fi
  local v1=`echo -e "${1}" | tr -d '[[:space:]]'`
  local v2=`echo -e "${2}" | tr -d '[[:space:]]'`
  local v1_sub=`sub_ver $v1`
  local v2_sub=`sub_ver $v2`
  if (( v1_sub > v2_sub )); then
    echo ">"
  elif (( v1_sub < v2_sub )); then
    echo "<"
  else
    version_compare `cut_dot $v1_sub $v1` `cut_dot $v2_sub $v2`
  fi
}

### Usage:

version_compare "1.2.3" "1.2.4"
# Output: <

ক্রেডিট @ শেলম্যানের কাছে যায়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.