Detectar la versión de Python en el script de shell

84

Me gustaría detectar si Python está instalado en un sistema Linux y, si lo está, qué versión de Python está instalada.

¿Cómo puedo hacerlo? ¿Hay algo más elegante que analizar la salida de "python --version"?

TheRealNeo
fuente
4
¿Por qué Python --version es desagradable? ¿Quizás / usr / bin / env python --version?
Hyperboreus
3
lo que quise decir con "sin gracia" es que el formato de la cadena puede cambiar en el futuro, invalidando el análisis de la cadena.
TheRealNeo
Python 2.4 devuelve un error para python --version. Necesitas usar python -V.
jww

Respuestas:

80

Podrías usar algo como lo siguiente:

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

La tupla está documentada aquí . Puede expandir el código de Python anterior para formatear el número de versión de una manera que se adapte a sus requisitos o, de hecho, para realizar comprobaciones.

Deberá verificar $?su script para manejar el caso donde pythonno se encuentra.

PD: Estoy usando una sintaxis un poco extraña para asegurar la compatibilidad con Python 2.xy 3.x.

NPE
fuente
6
También puede almacenar los resultados en una variable: export PYTHON_VERSION=`python -c 'import sys; version=sys.version_info[:3]; print("{0}.{1}.{2}".format(*version))'`usando esa solución. Mucho mejor que las expresiones regulares a continuación.
DragonTux
2
Para cualquier otra persona que aterrice aquí porque quiere asegurarse de que se haya instalado una determinada versión de Python: estoy usando esto junto con una afirmación, para poder usarlo en un script bash como este:if ! python3 -c 'import sys; assert sys.version_info >= (3,6)' > /dev/null; then
Thomas
31
python -c 'import sys; print sys.version_info'

o, legible por humanos:

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

También puedes usar esto:

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

Usé la respuesta de Jahid junto con Extraer el número de versión de una cadena para hacer algo escrito puramente en shell. También solo devuelve un número de versión y no la palabra "Python". Si la cadena está vacía, Python no está instalado.

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

Y digamos que desea comparar el número de versión para ver si está usando una versión actualizada de Python, use lo siguiente para eliminar los puntos en el número de versión. Luego, puede comparar versiones utilizando operadores enteros como "Quiero una versión de Python mayor que 2.7.0 y menor que 3.0.0". Referencia: $ {var // Pattern / Replacement} en 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
fuente
2
Bien, gracias por esto, pero el problema es que algunas versiones de python devuelven 4 dígitos y otras con 3 dígitos, por ejemplo, Python 2.7.12, así que comparar 2712 con 300 no funciona :(
Lilás
Se vuelve menos simple hacerlo, pero podría obtener el valor entero 2712, pegue '0'. detrás de él, luego compárelo con '0.300' usando la lógica que se encuentra en stackoverflow.com/questions/11237794/…
Sohrab T
12

Puede usar el módulo de plataforma que forma parte de la biblioteca estándar de Python:

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

Este módulo le permite imprimir solo una parte de la cadena de la versión:

$ python -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor); print(patch)'
2
6
9
logc
fuente
De hecho, el módulo plaftorm parece estar hecho para eso. Sin embargo, esto parece un poco inferior al uso de sys.version_info porque el módulo de plataforma solo apareció en Python 2.3, mientras que sys.version_info apareció en Python 2.0
TheRealNeo
10

Aquí hay otra solución que usa hash para verificar si Python está instalado y sed para extraer los dos primeros números principales de la versión y comparar si está instalada la versión mínima

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

Puede usar este comando en 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
fuente
8

el uso de sys.hexversion podría ser útil si desea comparar la versión en el script de shell

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
fuente
6

Agregando a la larga lista de posibles soluciones, aquí hay una similar a la respuesta aceptada, excepto que esta tiene una verificación de versión simple incorporada:

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

esto devolverá 0 si Python está instalado y al menos versiones 3.5, y devolverá 1si:

  • Python no está instalado
  • Python IS instalado, pero su versión es inferior a la versión 3.5

Para verificar el valor, simplemente compare $?(asumiendobash ), como se ve en otras preguntas.

Tenga en cuenta que esto no permite verificar diferentes versiones Python2, ya que la frase anterior arrojará una excepción en Py2. Sin embargo, dado que Python2está saliendo por la puerta, esto no debería ser un problema.

Deepbrook
fuente
4

Detección de python versión 2+ o 3+ en un script de shell:

# !/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
fuente
3

Para verificar si CUALQUIER Python está instalado (considerando que está en la RUTA), es tan simple como:

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

los > /dev/null 2>&1 pieza está ahí solo para suprimir la salida.

Para obtener los números de versión también:

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

Salida de muestra con Python 3.5 instalado: "Python versión 3.5.0 está instalada".

Nota 1: La awk '{print $2}'parte no funcionará correctamente si Python no está instalado, así que o utilización dentro de la verificación como en el ejemplo anterior, o el uso grepsegún lo sugerido por Sohrab T . Aunquegrep -P usa la sintaxis de expresiones regulares de Perl y puede tener algunos problemas de portabilidad.

Nota 2: python --versiono python -Vpodría no funcionar con versiones de Python anteriores a la 2.5. En este caso, utilice python -c ...como se sugiere en otras respuestas.

Nikita
fuente
2

En caso de que necesite un script bash, que repita "NoPython" si Python no está instalado, y con la referencia de Python si está instalado, puede usar el siguiente check_python.shscript.

  • Para comprender cómo usarlo en su aplicación, también agregué my_app.sh.
  • Compruebe que funciona jugando con PYTHON_MINIMUM_MAJORyPYTHON_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
fuente
1
Exactamente lo que estaba buscando. ¡Gracias!
Andrey Semakin
1

Otra forma más de imprimir la versión de Python de una manera legible por máquina con solo el número de versión mayor y menor. Por ejemplo, en lugar de "3.8.3" imprimirá "38", y en lugar de "2.7.18" imprimirá "27".

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

Funciona tanto para Python 2 como para 3.

Andrey Semakin
fuente
0

Si necesita verificar si la versión es al menos 'alguna versión', entonces prefiero una solución que no haga suposiciones sobre el número de dígitos en las partes de la versión.

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

Esto funcionaría incluso con numeraciones como 2.12.32 o 3.12.0, etc. Inspirado por esta respuesta .

Mi-La
fuente
¿Alguna razón para -1?
Mi-La