Erkennen Sie die Python-Version im Shell-Skript

80

Ich möchte feststellen, ob Python auf einem Linux-System installiert ist und welche Python-Version installiert ist.

Wie kann ich es tun? Gibt es etwas Anmutigeres, als die Ausgabe von zu analysieren "python --version"?

TheRealNeo
quelle
4
Warum ist Python --version unanständig? Vielleicht / usr / bin / env Python - Version?
Hyperboreus
3
Was ich mit "ungraceful" gemeint habe, ist, dass sich das String-Format in Zukunft möglicherweise ändert, wodurch das Parsing von Strings ungültig wird.
TheRealNeo
Python 2.4 gibt einen Fehler für zurück python --version. Sie müssen verwenden python -V.
JWW

Antworten:

77

Sie könnten etwas in der folgenden Richtung verwenden:

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

Das Tupel ist hier dokumentiert . Sie können den obigen Python-Code erweitern, um die Versionsnummer so zu formatieren, dass sie Ihren Anforderungen entspricht, oder um sie tatsächlich zu überprüfen.

Sie müssen $?Ihr Skript einchecken , um den Fall zu behandeln, in dem pythones nicht gefunden wird.

PS Ich verwende die etwas seltsame Syntax, um die Kompatibilität mit Python 2.x und 3.x sicherzustellen.

NPE
quelle
6
Sie können die Ergebnisse auch in einer Variablen speichern: export PYTHON_VERSION=`python -c 'import sys; version=sys.version_info[:3]; print("{0}.{1}.{2}".format(*version))'`mit dieser Lösung. Viel schöner als das Regex-Zeug unten.
DragonTux
1
Für alle anderen, die hier landen, weil Sie sicherstellen möchten, dass eine bestimmte Python-Version installiert ist: Ich verwende diese zusammen mit einer Zusicherung, damit ich sie in einem Bash-Skript wie diesem verwenden kann:if ! python3 -c 'import sys; assert sys.version_info >= (3,6)' > /dev/null; then
Thomas
30
python -c 'import sys; print sys.version_info'

oder für Menschen lesbar:

python -c 'import sys; print(".".join(map(str, sys.version_info[:3])))'
Fred Foo
quelle
17

Sie können dies auch verwenden:

pyv="$(python -V 2>&1)"
echo "$pyv"
Jahid
quelle
14

Ich habe Jahids Antwort zusammen mit der Versionsnummer aus einem String extrahieren verwendet , um etwas zu erstellen , das rein in Shell geschrieben ist. Es wird auch nur eine Versionsnummer zurückgegeben und nicht das Wort "Python". Wenn die Zeichenfolge leer ist, wird Python nicht installiert.

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

Angenommen, Sie möchten die Versionsnummer vergleichen, um festzustellen, ob Sie eine aktuelle Version von Python verwenden. Entfernen Sie die Punkte in der Versionsnummer wie folgt. Dann können Sie Versionen mit ganzzahligen Operatoren wie "Ich möchte eine Python-Version größer als 2.7.0 und kleiner als 3.0.0" vergleichen. Referenz: $ {var // Pattern / Replacement} in 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.
quelle
2
Schön, danke dafür, aber das Problem ist, dass einige Versionen von Python 4 Ziffern und andere 3 Ziffern zurückgeben, z. B. Python 2.7.12, so dass der Vergleich von 2712 mit 300 nicht funktioniert :(
Lilás
Es wird weniger einfach, dies zu tun, aber Sie könnten den ganzzahligen Wert 2712 erhalten, indem Sie '0' bleiben. dahinter, dann vergleiche es mit '0.300' unter Verwendung der Logik in stackoverflow.com/questions/11237794/…
Sohrab T
10

Hier ist eine andere Lösung, die mithilfe von Hash überprüft, ob Python installiert und sed ist, um die ersten beiden Hauptnummern der Version zu extrahieren und zu vergleichen, ob die Mindestversion installiert ist

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
quelle
9

Sie können das Plattformmodul verwenden, das Teil der Standard-Python-Bibliothek ist:

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

Mit diesem Modul können Sie nur einen Teil der Versionszeichenfolge drucken:

$ python -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor); print(patch)'
2
6
9
logc
quelle
In der Tat scheint das Plaftorm-Modul dafür gemacht zu sein. Dies scheint jedoch der Verwendung von sys.version_info etwas unterlegen zu sein, da das Plattformmodul nur in Python 2.3 erschien, während sys.version_info in Python 2.0
TheRealNeo
8

Die Verwendung von sys.hexversion kann hilfreich sein, wenn Sie die Version im Shell-Skript vergleichen möchten

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
quelle
8

Sie können diesen Befehl in bash verwenden:

PYV=`python -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";`
echo $PYV
Farsheed
quelle
6

Neben der langen Liste möglicher Lösungen ist hier eine ähnliche wie bei der akzeptierten Antwort aufgeführt - mit der Ausnahme, dass eine einfache Versionsprüfung integriert ist:

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

Dies gibt 0 zurück, wenn Python installiert ist und mindestens Versionen 3.5, und gibt zurück, 1wenn:

  • Python ist nicht installiert
  • Python ist installiert, aber seine Version ist kleiner als die Version 3.5

Um den Wert zu überprüfen, vergleichen Sie einfach $?(vorausgesetzt bash), wie in anderen Fragen gezeigt.

Beachten Sie, dass dies nicht das Überprüfen verschiedener Versionen erlaubt, Python2da der obige Einzeiler eine Ausnahme in Py2 auslöst. Da dies Python2jedoch auf dem Weg zur Tür ist, sollte dies kein Problem sein.

Deepbrook
quelle
3

Um zu überprüfen, ob ANY Python installiert ist (wenn man bedenkt, dass es sich auf dem PATH befindet), ist es so einfach wie:

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

Der > /dev/null 2>&1Teil dient nur zur Unterdrückung der Ausgabe.

So erhalten Sie auch die Versionsnummern:

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

Beispielausgabe mit installiertem Python 3.5: "Python Version 3.5.0 ist installiert."

Hinweis 1: Das awk '{print $2}'Teil funktioniert nicht ordnungsgemäß, wenn Python nicht installiert ist. Verwenden Sie es daher entweder innerhalb der Prüfung wie im obigen Beispiel oder grepwie von Sohrab T vorgeschlagen . Obwohl grep -PAnwendungen Perl regexp - Syntax und möglicherweise einige Portabilität Probleme haben.

Hinweis 2: python --versionoder python -Vfunktioniert möglicherweise nicht mit Python-Versionen vor 2.5. In diesem Fall python -c ...wie in anderen Antworten vorgeschlagen verwenden.

Nikita
quelle
3

Erkennung von Python Version 2+ oder 3+ in einem Shell-Skript:

# !/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
quelle
2

Wenn Sie ein Bash-Skript benötigen, das "NoPython" wiedergibt, wenn Python nicht installiert ist, und mit der Python-Referenz, wenn es installiert ist, können Sie das folgende check_python.shSkript verwenden.

  • Um zu verstehen, wie man es in Ihrer App verwendet, habe ich auch hinzugefügt my_app.sh.
  • Überprüfen Sie, ob es funktioniert, indem Sie mit PYTHON_MINIMUM_MAJORund spielenPYTHON_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
quelle
1
Genau das, wonach ich gesucht habe. Vielen Dank!
Andrey Semakin
1

Eine weitere Möglichkeit, die Python-Version maschinenlesbar nur mit der Haupt- und Nebenversionsnummer zu drucken. Beispielsweise wird anstelle von "3.8.3" "38" und anstelle von "2.7.18" "27" gedruckt.

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

Funktioniert sowohl für Python 2 als auch für Python 3.

Andrey Semakin
quelle
0

Wenn Sie überprüfen müssen, ob es sich bei der Version mindestens um eine Version handelt, bevorzuge ich eine Lösung, bei der keine Annahmen über die Anzahl der Stellen in den Versionsteilen getroffen werden.

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

Dies würde sogar mit Nummerierungen wie 2.12.32 oder 3.12.0 usw. funktionieren. Inspiriert von dieser Antwort .

Mi-La
quelle
Irgendein Grund für -1?
Mi-La