शेल स्क्रिप्ट में प्रोग्राम के संस्करण की तुलना कैसे करें?


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

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
-Vsort(1)इस प्रकार यह समाधान गैर-पोर्टेबल का एक GNU विस्तार है ।
स्टीफन

1
sort -nअंक संस्करणों के मामले में बहुत अधिक उसी तरह काम करता है।
रॉकलाइट नाइट

1
@LucianoAndressMartini, देखें कि आप मेरे संपादन के बारे में क्या सोचते हैं।
वाइल्डकार्ड

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
}

आप इसे संशोधित कर सकते हैं और इसे gcc संस्करण जाँच के लिए उपयोग कर सकते हैं।


+1 यह अन्य यूनिक्स की तरह संगत है? (मेरा समाधान नहीं है)
लुसियानो एंड्रेस मार्टिनी

1

हम एक GNU मेकफाइल में बहुत सारे वर्जन चेकिंग करते थे। हम मेकफाइल सुविधाओं के माध्यम से बाहर आ गए। हमें पुराने बिनुटिल्स और छोटी गाड़ी के कंपाइलरों का पता लगाना था और उन्हें मक्खी पर बैठाना था।

पैटर्न हम इस्तेमाल किया था:

#!/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"

(१) यह पहले से दिए गए उत्तरों का मामूली बदलाव है। आप एक स्पष्टीकरण जोड़कर मूल्य जोड़ सकते हैं, जो अभी तक पोस्ट नहीं किया गया है। (२)  printf '%s\n'काफी अच्छा है; printfआवश्यकतानुसार प्रारूप स्ट्रिंग को दोहराएगा।
जी-मैन ने कहा कि 'बहाल मोनिका'

मैं आम तौर पर मौजूदा उत्तरों को संपादित करना पसंद करता हूं, लेकिन उनमें से आधे को हटाना बहुत मुश्किल है: दूसरे वे मूल्य देख सकते हैं जहां मैं नहीं। वर्बोज़ स्पष्टीकरण के लिए भी। थोड़ा ही काफी है।
19

मुझे पता है कि printfप्रारूप स्ट्रिंग को दोहराता है, लेकिन मैं (की कमी है!) इसके लिए सिंटैक्स IMHO अस्पष्ट है; इसलिए मैं इसका उपयोग केवल तभी करता हूं जब = जब तर्कों की संख्या बड़ी या परिवर्तनशील हो।
19

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: <

श्रेय @Shellman को जाता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.