Bash 버전이> = 주어진 버전 번호인지 확인하십시오.


12

Bash 버전 번호가> =인지 특정 숫자인지 테스트해야합니다. 예를 들어

$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

연관 배열을 사용하려면 bash 버전 번호가> = 4 여야합니다.

내 bash 스크립트에서 가장 우아하고 효율적이며 읽기 쉬운 방식으로 한 줄짜리 테스트를하고 싶지만 다른 접근법도 허용됩니다.


$BASH_VERSION$BASH_VERSINFO변수 를 살펴 보셨습니까 ?
steeldriver

@steeldriver 아니요. 게시하려는 경우 bash 관련 사례에서 허용되는 답변입니다. 그러나 다른 경우 환경 변수를 사용하지 못할 수 있습니다.
WinEunuuchs2Unix


bash에만 관련된 @SergiyKolodyazhnyy. bash 버전 번호 만 검사하는 bash one-liner 또는 스크립트 / 함수를 찾고 있지만 궁극적 인 목표는 아닙니다. --version출력 을 추가 하고 테스트하여 모든 프로그램을 확인하는 일반적인 루틴 은 원래 의도였습니다. 그에 따라 질문을 편집했습니다.
WinEunuuchs2Unix

버전 번호 형식은 프로그램마다 크게 다릅니다. 버전 세부 정보를보고하는 방식도 크게 다릅니다. 무작위 프로그램의 버전을 확인하는 방법을 요청하는 것은 실용적이지 않습니다. 이 질문은 너무 광범위합니다.
muru

답변:


16

시험:

$ [ "${BASH_VERSINFO:-0}" -ge 4 ] && echo "bash supports associative arrays"
bash supports associative arrays

BASH_VERSINFO멤버가이 bash 인스턴스에 대한 버전 정보를 보유하는 읽기 전용 배열 변수입니다. bash 2.0과 함께 도입되었으므로 모든 bash 버전에서 지원 될 것입니다. 그러나 신중 0을 기하기 위해이 변수가 설정되어 있지 않은 이전 버전 bash 의 기본값 인 기본값을 포함합니다 .

다른 프로그램에서 버전 정보 추출

LibreOffice, Python, 커널 등에 대해 물었습니다.

LibreOffice는 다음과 같은 버전 정보를 생성합니다.

$ libreoffice --version
LibreOffice 5.2.6.2 20m0(Build:2)

버전 번호를 추출하려면 다음을 수행하십시오.

$ libreoffice --version | cut -d' ' -f2
5.2.6.2

파이썬의 경우 :

$ python -c 'import platform; print(platform.python_version())'
2.7.13

커널 버전을 얻으려면 다음을 사용하십시오 uname.

$ uname -r
4.9.0-2-amd64

좋은 답변입니다! 참고로 귀하의 uname -r"4.9.0-2-amd64"는 실제 버전 번호가 클 때 정기적으로 bash 테스트를 수행하여 "4.11.1-041101-generic"보다 더 크게 테스트 할 수 있습니다.
WinEunuuchs2Unix

2
유닉스 파이썬 도구는 버전 문자열을 정확하게 비교할 수 있습니다. 참조 파이썬에서 비교 버전 문자열을
wjandrea

John-- 파이썬 예로 단축 할 수 $ python --version있는 돌아갑니다 Python 2.7.12. @ wjandrea-- 링크 +1 감사합니다. 아마도 모든 프로그램 이름과 최소 버전 번호의 테이블을 만들 수 있습니다. 그런 다음 python제공 한 링크 의 수정 된 사본으로 테이블을 전달하십시오 . 컴파일 된 파이썬 만 호출 할 수 있기 때문에 grub바이너리 또는 쉘에서 가능한 바이너리가 있다고 생각할 것입니다.
WinEunuuchs2Unix

9

버전 번호를 비교하는 대신 기능 자체를 직접 테스트 할 수 있습니다. declare -A반환 2(배쉬 3.2 이상)가 인식 할 수없는 경우 -A, 그에 대한 시험 (그것은 또한 오류를 인쇄) 그래서 :

unset assoc
if ! declare -A assoc ; then
    echo "associative arrays not supported!"
    exit 1
fi

( 비 연관 배열 인 declare -A var경우에도 실패 var하므로 unset먼저 배열 입니다.)

나는 누군가가 Bash에서 기능을 백 포트한다고 가정하지는 않지만 일반적으로 버전이 아닌 기능을 확인하는 것이 더 적절합니다. Bash의 경우에도 누군가 기능이 제한된 버전을 컴파일 할 수 있습니다 ...


보다 일반적인 버전 번호 테스트는 1) 테스트 할 올바른 버전 번호를 찾는 방법과 2) 다른 값과 비교하는 방법의 두 부분으로 구성됩니다.

첫 번째는 더 어려운 것입니다. 대부분의 프로그램은 명령 줄과 같은 플래그 자신의 버전 번호 말 --version또는 -v하지만, 출력 형식은 다양하며 프로그램 버전 번호를 따기 어려울 수 있습니다. 그런 다음 같은 프로그램의 여러 버전을 동시에 설치해야하는 문제가 있습니다.

두 번째는 버전 번호의 형식에 대한 지식에 달려 있습니다. 데비안 스타일 버전 번호를dpkg 비교할 수 있습니다 ( 서머 타입 버전을 서브셋으로 포함한다고 생각합니다 ).

if dpkg --compare-versions 4.3.30 ge 4.0.0 ; then
    echo "it's version 4.x"
fi

또는 위의 내용을 결합하십시오.

bashver=$( bash --version | sed -Ee 's/GNU bash, version ([0-9.]+).*/\1/;q' )
if dpkg --compare-versions "$bashver" ge 4.0.0 ; then
    echo "'bash' in your path is version 4.x"
fi

5

달성하고자하는 것에 접근하는 몇 가지 방법이 있습니다.

1. $ BASH_VERSION을 사용하십시오.

$BASH_VERSION변수가 무엇인지 보는 것만으로 충분 합니다. 개인적으로 나는 서브 쉘을 다음과 같이 사용합니다 :

$ (read -d "." version trash <<< $BASH_VERSION; echo "$version" )
4

그 주 <<<당신이 그것을 사용하는 거라면 여기-문서에 대한 구문은, 이식 할 수 없습니다 /bin/sh대쉬 우분투에 있고 다른 시스템에 뭔가 다른 될 수있는,

다른 방법은 사례 설명 또는 if 문을 사용하는 것입니다. 개인적으로, 나는 이것을 할 것입니다 :

bash-4.3$ case $BASH_VERSION in 4.*) echo "Can use associative arrays";; ?) echo "can't use associative arrays" ;; esac
Can use associative arrays

아마도 이식성을 위해 아마도 그러한 변수가 처음에 다음과 같은 것으로 설정되어 있는지 확인해야합니다. [ -n $BASH_VERSION ]

이것은 스크립트에서 사용되는 함수로 완전히 다시 쓸 수 있습니다. 긴 줄 :

#!/bin/bash
version_above_4(){
    # check if $BASH_VERSION is set at all
    [ -z $BASH_VERSION ] && return 1

    # If it's set, check the version
    case $BASH_VERSION in 
        4.*) return 0 ;;
        ?) return 1;; 
    esac
}

if version_above_4
then
    echo "Good"
else
    echo "No good"
fi

비록 이것이 훨씬 낫지 만 이것은 하나의 라이너가 아닙니다. 수량보다 품질.

2. 설치된 내용 확인

이를 위해 다음 apt-cache policy과 같은 출력을 필터링해야합니다.

$ apt-cache policy bash | awk -F '[:.]' '/Installed:/{printf "%s\n",substr($2,2)}'
4

dpkg-query를 통한 일부 필터링과 함께 사용할 수도 있습니다 awk.

$ dpkg-query -W bash | awk '{print substr($2,1,1)}'   
4

시스템에 설치되어 있지 dpkg않거나 apt(예 : RHEL 또는 FreeBSD) 설치되어 있으면 아무 소용이 없으므로 이식성 이 없습니다.

3. 오류가있는 경우 set -e를 사용하여 스크립트를 종료하십시오.

그것을 해결하는 한 가지 방법은 단순히 연관 배열을 사용하여 사용할 bash수 없을 때 종료 하는 것입니다. set -e아래 줄 #!/bin/bash은 스크립트가 연관 배열을 사용할 수없는 경우 스크립트를 종료 할 수있게합니다.

이를 위해서는 사용자에게 다음과 같이 명시 적으로 알려 주어야합니다. "배치 버전 4.3 이상이 필요합니다. 그렇지 않으면 스크립트가 작동하지 않습니다." 일부는 이것이 실제로 소프트웨어 개발에 대한 좋은 접근 방식이 아니라고 주장 할 수도 있지만 책임은 사용자에게 있습니다.

4. 모든 희망을 버리고 이식 가능한 POSIX 호환 스크립트 작성

bash스크립트는 구문이 Bourne 쉘과 호환되지 않기 때문에 이식성이 없습니다. 작성중인 스크립트가 우분투뿐만 아니라 다양한 시스템에서 사용될 예정이라면 모든 희망을 버리고 연관 배열 이외의 것을 사용하는 방법을 찾으십시오. 여기에는 두 개의 배열이 있거나 구성 파일을 구문 분석하는 것이 포함될 수 있습니다. 구문이 적어도 다른 언어 인 Perl 또는 Python으로 전환하는 것도 고려하십시오 bash.


연관 배열은 섹션 4에서 제안한대로 "두 배열"의 두 번째입니다. 유일한 목적은 키 "path / to / file-name"을 보유하는 것이며 값은 기본 배열 내의 인덱스입니다. 연관 배열은 현재 순차적 인 일반 인덱스 배열로 검색 속도를 높이기 위해 만들어졌습니다. 어쨌든 파이썬에 주목하고 있지만 현재의 bash 호환성은 Ubuntu 및 아마도 Bash for Windows 10에 중점을 둡니다. 나는 맞춤식 스크립트를 좋아합니다. 예를 들어 yad --version반환 0.37.0 (GTK+ 3.18.9)하지만 새로운 기능은 현재에 0.39있습니다.
WinEunuuchs2Unix

위대하고 유용한 답변. 감사합니다!
qodeninja

2

하나의 라이너는 불가능하지만 bash 스크립트는 가능합니다

Stack Overflow에서 답변을 그리는 스크립트를 개발했습니다. 이러한 답변 중 하나가 2004 년 DKMS 응용 프로그램에 대한 Dell 직원의 버전 번호 비교 결과를 가져 왔습니다.

코드

아래의 bash 스크립트는 명령을 사용하여 실행 파일로 표시해야합니다 chmod a+x script-name. 나는 이름을 사용하고 있습니다 /usr/local/bin/testver:

#!/bin/bash

# NAME: testver
# PATH: /usr/local/bin
# DESC: Test a program's version number >= to passed version number
# DATE: May 21, 2017. Modified August 5, 2019.

# CALL: testver Program Version

# PARM: 1. Program - validated to be a command
#       2. Version - validated to be numberic

# NOTE: Extracting version number perl one-liner found here:
#       http://stackoverflow.com/questions/16817646/extract-version-number-from-a-string

#       Comparing two version numbers code found here:
#       http://stackoverflow.com/questions/4023830/how-compare-two-strings-in-dot-separated-version-format-in-bash

# Map parameters to coder-friendly names.
Program="$1"
Version="$2"

# Program name must be a valid command.
command -v $Program >/dev/null 2>&1 || { echo "Command: $Program not found. Check spelling."; exit 99; }

# Passed version number must be valid format.
if ! [[ $Version =~ ^([0-9]+\.?)+$ ]]; then
    echo "Version number: $Version has invalid format. Aborting.";
    exit 99
fi

InstalledVersion=$( "$Program" --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )
# echo "Installed Version: $InstalledVersion"

if [[ $InstalledVersion =~ ^([0-9]+\.?)+$ ]]; then
    l=(${InstalledVersion//./ })
    r=(${Version//./ })
    s=${#l[@]}
    [[ ${#r[@]} -gt ${#l[@]} ]] && s=${#r[@]}

    for i in $(seq 0 $((s - 1))); do
        # echo "Installed ${l[$i]} -gt Test ${r[$i]}?"
        [[ ${l[$i]} -gt ${r[$i]} ]] && exit 0 # Installed version > test version.
        [[ ${l[$i]} -lt ${r[$i]} ]] && exit 1 # Installed version < test version.
    done

    exit 0 # Installed version = test version.
else
    echo "Invalid version number found for command: $Program"
    exit 99
fi

echo "testver - Unreachable code has been reached!"
exit 255
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.