Wykryj wersję Pythona w skrypcie powłoki

85

Chciałbym wykryć, czy w systemie Linux jest zainstalowany język Python, a jeśli tak, to jaka wersja języka Python jest zainstalowana.

Jak mogę to zrobić? Czy jest coś bardziej wdzięcznego niż analizowanie wyniku "python --version"?

TheRealNeo
źródło
4
dlaczego Python - wersja nie wdzięczna? Może / usr / bin / env python --version?
Hyperboreus
3
co miałem na myśli, mówiąc o „niezręcznym”, to fakt, że format ciągu może się zmienić w przyszłości, unieważniając jego analizę.
TheRealNeo
Python 2.4 zwraca błąd dla python --version. Musisz użyć python -V.
jww

Odpowiedzi:

80

Możesz użyć czegoś z następujących linii:

$ python -c 'import sys; print(sys.version_info[:])'
(2, 6, 5, 'final', 0)

Krotka jest udokumentowane tutaj . Możesz rozwinąć powyższy kod Pythona, aby sformatować numer wersji w sposób, który pasowałby do twoich wymagań, lub faktycznie, aby sprawdzić go.

Będziesz musiał sprawdzić $?swój skrypt, aby obsłużyć przypadek, w którym pythonnie został znaleziony.

PS Używam nieco dziwnej składni, aby zapewnić zgodność zarówno z Pythonem 2.x, jak i 3.x.

NPE
źródło
6
Możesz również przechowywać wyniki w zmiennej: export PYTHON_VERSION=`python -c 'import sys; version=sys.version_info[:3]; print("{0}.{1}.{2}".format(*version))'`używając tego rozwiązania. O wiele ładniejsze niż poniższe wyrażenia regularne.
DragonTux
2
Dla każdego, kto wyląduje tutaj, ponieważ chcesz mieć pewność, że pewna wersja Pythona jest zainstalowana: używam tego razem z assertem, więc mogę go użyć w skrypcie bash takim jak ten:if ! python3 -c 'import sys; assert sys.version_info >= (3,6)' > /dev/null; then
Thomas
31
python -c 'import sys; print sys.version_info'

lub czytelne dla człowieka:

python -c 'import sys; print(".".join(map(str, sys.version_info[:3])))'
Fred Foo
źródło
18

Możesz też tego użyć:

pyv="$(python -V 2>&1)"
echo "$pyv"
Jahid
źródło
14

Użyłem odpowiedzi Jahida wraz z wyodrębnieniem numeru wersji z łańcucha, aby stworzyć coś napisanego wyłącznie w powłoce. Zwraca również tylko numer wersji, a nie słowo „Python”. Jeśli ciąg jest pusty, Python nie jest instalowany.

version=$(python -V 2>&1 | grep -Po '(?<=Python )(.+)')
if [[ -z "$version" ]]
then
    echo "No Python!" 
fi

Powiedzmy, że chcesz porównać numer wersji, aby sprawdzić, czy używasz aktualnej wersji Pythona, użyj poniższego, aby usunąć kropki w numerze wersji. Następnie możesz porównać wersje przy użyciu operatorów całkowitych, takich jak „Chcę wersję Pythona większą niż 2.7.0 i mniejszą niż 3.0.0”. Źródła: $ {var // Pattern / Replace} w http://tldp.org/LDP/abs/html/parameter-substitution.html

parsedVersion=$(echo "${version//./}")
if [[ "$parsedVersion" -lt "300" && "$parsedVersion" -gt "270" ]]
then 
    echo "Valid version"
else
    echo "Invalid version"
fi
Sohrab T
źródło
2
Fajnie, dzięki za to, ale problem polega na tym, że niektóre wersje Pythona zwracają 4 cyfry, a inne 3 cyfry, np. Python 2.7.12, więc porównanie 2712 z 300 nie działa :(
Lilás
Staje się to mniej proste, ale możesz uzyskać liczbę całkowitą 2712, trzymać „0”. za nim, a następnie porównaj z wartością „0.300”, używając logiki znalezionej na stackoverflow.com/questions/11237794/ ...
Sohrab T
12

Możesz użyć modułu platformy, który jest częścią standardowej biblioteki Pythona:

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

Ten moduł umożliwia wydrukowanie tylko części ciągu wersji:

$ python -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor); print(patch)'
2
6
9
logc
źródło
Rzeczywiście, wydaje się, że moduł plaftorm jest do tego stworzony. Wydaje się to jednak nieco gorsze od używania sys.version_info, ponieważ moduł platformy pojawił się tylko w Pythonie 2.3, podczas gdy sys.version_info pojawił się w Pythonie 2.0
TheRealNeo
10

Oto inne rozwiązanie wykorzystujące hash do sprawdzenia, czy Python jest zainstalowany i seda do wyodrębnienia dwóch pierwszych głównych liczb wersji i porównania, czy zainstalowana jest minimalna wersja

if ! hash python; then
    echo "python is not installed"
    exit 1
fi

ver=$(python -V 2>&1 | sed 's/.* \([0-9]\).\([0-9]\).*/\1\2/')
if [ "$ver" -lt "27" ]; then
    echo "This script requires python 2.7 or greater"
    exit 1
fi
Lilás
źródło
9

Możesz użyć tego polecenia w bash:

PYV=`python -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";`
echo $PYV
Farsheed
źródło
8

użycie sys.hexversion może być przydatne, jeśli chcesz porównać wersję w skrypcie powłoki

ret=`python -c 'import sys; print("%i" % (sys.hexversion<0x03000000))'`
if [ $ret -eq 0 ]; then
    echo "we require python version <3"
else 
    echo "python version is <3"
fi
k2s
źródło
6

Dodając do długiej listy możliwych rozwiązań, oto odpowiedź podobna do zaakceptowanej odpowiedzi - z wyjątkiem tego, że ma wbudowaną prostą kontrolę wersji:

python -c 'import sys; exit(1) if sys.version_info.major < 3 and sys.version_info.minor < 5 else exit(0)'

to zwróci 0, jeśli jest zainstalowany Python i przynajmniej wersje 3.5, i zwróci, 1jeśli:

  • Python nie jest zainstalowany
  • Python jest zainstalowany, ale jego wersja jest mniejsza niż wersja 3.5

Aby sprawdzić wartość, po prostu porównaj $?(zakładającbash ), jak widać w innych pytaniach.

Uważaj, to nie pozwala na sprawdzanie różnych wersji Python2- ponieważ powyższa jednolinijka zgłosi wyjątek w Py2. Ponieważ jednak Python2jest w drodze do drzwi, nie powinno to stanowić problemu.

deepbrook
źródło
4

Wykrywanie języka Python w wersji 2+ lub 3+ w skrypcie powłoki:

# !/bin/bash
ver=$(python -c"import sys; print(sys.version_info.major)")
if [ $ver -eq 2 ]; then
    echo "python version 2"
elif [ $ver -eq 3 ]; then
    echo "python version 3"
else 
    echo "Unknown python version: $ver"
fi
Robert Lujo
źródło
3

Aby sprawdzić, czy DOWOLNY Python jest zainstalowany (biorąc pod uwagę, że znajduje się na PATH), jest to tak proste, jak:

if which python > /dev/null 2>&1;
then
    #Python is installed
else
    #Python is not installed
fi

> /dev/null 2>&1Część jest nie tylko do wyjścia stłumić.

Aby uzyskać również numery wersji:

if which python > /dev/null 2>&1;
then
    #Python is installed
    python_version=`python --version 2>&1 | awk '{print $2}'`
    echo "Python version $python_version is installed."

else
    #Python is not installed
    echo "No Python executable is found."
fi

Przykładowe dane wyjściowe z zainstalowanym językiem Python 3.5: „Zainstalowano język Python w wersji 3.5.0”.

Uwaga 1: awk '{print $2}'część nie będzie działać prawidłowo, jeśli nie jest zainstalowany Python, więc zarówno do użytku wewnątrz kontroli, jak w powyższym przykładzie, lub wykorzystania grepzgodnie z sugestią Sohraba T . Chociaż grep -Pużywa składni wyrażeń regularnych Perl i może mieć pewne problemy z przenośnością.

Uwaga 2: python --versionlub python -Vmoże nie działać z wersjami Pythona starszymi niż 2.5. W tym przypadku użyj python -c ...zgodnie z sugestiami innych odpowiedzi.

Nikita
źródło
2

W przypadku, gdy potrzebujesz skryptu bash, który powtarza "NoPython", jeśli Python nie jest zainstalowany, oraz z odwołaniem do Pythona, jeśli jest zainstalowany, możesz użyć następującego check_python.shskryptu.

  • Aby zrozumieć, jak go używać w swojej aplikacji, dodałem również my_app.sh.
  • Sprawdź, czy działa, grając z PYTHON_MINIMUM_MAJORiPYTHON_MINIMUM_MINOR

check_python.sh

#!/bin/bash

# Set minimum required versions
PYTHON_MINIMUM_MAJOR=3
PYTHON_MINIMUM_MINOR=6

# Get python references
PYTHON3_REF=$(which python3 | grep "/python3")
PYTHON_REF=$(which python | grep "/python")

error_msg(){
    echo "NoPython"
}

python_ref(){
    local my_ref=$1
    echo $($my_ref -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor);')
}

# Print success_msg/error_msg according to the provided minimum required versions
check_version(){
    local major=$1
    local minor=$2
    local python_ref=$3
    [[ $major -ge $PYTHON_MINIMUM_MAJOR && $minor -ge $PYTHON_MINIMUM_MINOR ]] && echo $python_ref || error_msg
}

# Logic
if [[ ! -z $PYTHON3_REF ]]; then
    version=($(python_ref python3))
    check_version ${version[0]} ${version[1]} $PYTHON3_REF
elif [[ ! -z $PYTHON_REF ]]; then
    # Didn't find python3, let's try python
    version=($(python_ref python))
    check_version ${version[0]} ${version[1]} $PYTHON_REF
else
    # Python is not installed at all
    error_msg
fi

my_app.sh

#!/bin/bash
# Add this before your app's code
PYTHON_REF=$(source ./check_python.sh) # change path if necessary
if [[ "$PYTHON_REF" == "NoPython" ]]; then
    echo "Python3.6+ is not installed."
    exit
fi

# This is your app
# PYTHON_REF is python or python3
$PYTHON_REF -c "print('hello from python 3.6+')";
Meir Gabay
źródło
1
Dokładnie to, czego szukałem. Dziękuję Ci!
Andrey Semakin
1

Jeszcze inny sposób drukowania wersji Pythona w sposób czytelny dla komputera, z podaniem tylko numeru wersji głównej i pobocznej. Na przykład zamiast „3.8.3” wypisze „38”, a zamiast „2.7.18” wypisze „27”.

python -c "import sys; print(''.join(map(str, sys.version_info[:2])))"

Działa zarówno dla Pythona 2, jak i 3.

Andrey Semakin
źródło
0

Jeśli chcesz sprawdzić, czy wersja jest przynajmniej „jakąś wersją”, to wolę rozwiązanie, które nie zakłada z góry liczby cyfr w częściach wersji.

VERSION=$(python -V 2>&1 | cut -d\  -f 2) # python 2 prints version to stderr
VERSION=(${VERSION//./ }) # make an version parts array 
if [[ ${VERSION[0]} -lt 3 ]] || [[ ${VERSION[0]} -eq 3 && ${VERSION[1] -lt 5 ]] ; then
    echo "Python 3.5+ needed!" 1>&2
    return 1
fi

To zadziałałoby nawet z numeracją taką jak 2.12.32 lub 3.12.0, itp. Zainspirowany tą odpowiedzią .

Mi-La
źródło
Jakiś powód dla -1?
Mi-La
0

Najłatwiej byłoby:

if ! python3 --version ; then
    echo "python3 is not installed"
    exit 1
fi

# In the form major.minor.micro e.g. '3.6.8'
# The second part excludes the 'Python ' prefix 
PYTHON_VERSION=`python3 --version | awk '{print $2}'`
Giorgos Myrianthous
źródło