Implementación de Python y portabilidad/usr/bin/env
executable environment (5)
Al comienzo de todos mis scripts Python ejecutables, coloqué la línea shebang :
#!/usr/bin/env python
Estoy ejecutando estos scripts en un sistema donde env python
produce un entorno Python 2.2. Mis scripts fallan rápidamente porque tengo una verificación manual para una versión compatible de Python:
if sys.version_info < (2, 4):
raise ImportError("Cannot run with Python version < 2.4")
No quiero tener que cambiar la línea shebang en cada archivo ejecutable, si es posible; sin embargo, no tengo acceso administrativo a la máquina para cambiar el resultado de env python
y no quiero forzar una versión en particular, como en:
#!/usr/bin/env python2.4
Me gustaría evitar esto porque el sistema puede tener una versión más nueva que Python 2.4, o puede tener Python 2.5 pero no Python 2.4.
¿Cuál es la solución elegante?
[Editar:] No fui lo suficientemente específico al plantear la pregunta. Me gustaría que los usuarios ejecuten los scripts sin configuración manual (por ejemplo, alteración de ruta o enlace simbólico en ~/bin
y asegurar que su RUTA tenga ~/bin
antes del Python 2.2 camino). ¿Tal vez se requiera alguna utilidad de distribución para evitar los ajustes manuales?
"env" simplemente ejecuta lo primero que encuentra en la variable env de PATH. Para cambiar a una python diferente, anteponga el directorio del ejecutable de esa python a la ruta antes de invocar la secuencia de comandos.
Si está ejecutando las secuencias de comandos, entonces puede configurar su variable PATH para que apunte a un directorio privado bin primero:
$ mkdir ~/bin
$ ln -s `which python2.4` ~/bin/python
$ export PATH=~/bin:$PATH
Luego, cuando ejecutes tu script python, usarás python 2.4. Tendrá que cambiar sus scripts de inicio de sesión para cambiar su RUTA.
Alternativamente, ejecute su secuencia de comandos python con el intérprete explícito que desee:
$ /path/to/python2.4 <your script>
@morais: Es una idea interesante, pero creo que tal vez podamos dar un paso más. Tal vez haya una forma de utilizar el virtualenv de Ian Bicking para:
- Vea si estamos corriendo en un entorno aceptable para empezar, y si es así, no haga nada.
- Compruebe si existe un ejecutable específico de la versión en la
PATH
, es decir, compruebe sipython2.x
existefor x in reverse(range(4, 10))
. Si es así, vuelva a ejecutar el comando con el mejor intérprete. - Si no existe un intérprete mejor, use virtualenv para tratar de instalar una versión más nueva de Python de la versión anterior de Python y obtenga cualquier paquete de requisitos previos.
No tengo idea si Virtualenv es capaz de esto, así que me voy a meter la pata con él pronto. :)
Solución bastante hackosa: si su verificación falla, use esta función (que probablemente podría mejorarse significativamente) para determinar el mejor intérprete disponible, determine si es aceptable y, de ser así, vuelva a iniciar su secuencia de comandos con os.system o algo similar y su sistema. argv usando el nuevo intérprete.
import os
import glob
def best_python():
plist = []
for i in os.getenv("PATH").split(":"):
for j in glob.glob(os.path.join(i, "python2.[0-9]")):
plist.append(os.path.join(i, j))
plist.sort()
plist.reverse()
if len(plist) == 0: return None
return plist[0]
Aquí hay una solución si (1) está absolutamente configurado para usar shebangs y (2) si puede usar Autotools en su proceso de compilación.
AM_PATH_PYTHON
que puedes usar la macro de autoconf AM_PATH_PYTHON
para encontrar un binario mínimo de Python 2 . El how-to está aquí .
Entonces, su proceso sería:
- Emita un
AM_PATH_PYTHON(2.4)
en suconfigure.ac
- Cambie el nombre de todos sus scripts
.py
a.py.in
(en mi experiencia, esto no confundevi
) - Nombre todos los scripts de Python que desea generar con
AC_CONFIG_FILES
. - En lugar de comenzar con
#!/usr/bin/env python
, use#!@PYTHON@
Entonces tus scripts de Python resultantes siempre tendrán un shebang apropiado.
Entonces, tienes esta solución, al menos posible, si no es práctica.