2012-07-03 14 views
8

bin/env tengo este problema:

System A corre Ubuntu y Python 2.6 necesita para un montón de cosas diferentes.
Yo instalé Python 2.7 por separado en System A
System B tiene Python 2.7 natively.
Tratar con múltiples versiones de Python cuando los archivos tienen que usar pitón #/pitón

Tengo un script de python BLAH que dice #!/bin/env python arriba.
Más abajo se ejecuta otra secuencia de comandos SIGH, que arriba también dice: #!/bin/env python.

BLAH tiene que funcionar con System A o System B, y siempre hay que ejecutar Python 2.7

----
Parte de mi solución hasta el momento:
tener un guión envoltorio que primero trata de ver si which python apunta a Python 2.7
Si está bien, ejecute BLAH con esa ruta para python.
Si no, pruebe which python2.7 y use esa ruta para ejecutar BLAH, y agregue esa ruta a env PATH.

problema de esta solución es:

En System A (que Python 2.7 ha instalado por separado)
Cuando BLAH ejecuta, se ejecuta con Python 2.7 debido al guión envoltorio que escribí (bueno hasta ahora ..)
Cuando BLAH desova SIGH, SIGH utiliza el tinglado para encontrar pitón en el camino y entonces está en problemas porque está buscando pitón en env 's PATH y se debe buscar python2.7 en el camino.

¿Hay una manera limpia de manejar este problema?

¡Gracias de antemano!

+0

¿Se puede importar y ejecutar SIGH desde BLAH? –

+0

No estoy seguro de que necesite agregar la ruta que obtiene de 'which' a' PATH' - 'which' en realidad solo buscará rutas contenidas en' PATH'. – jedwards

Respuesta

9

Si usted tiene un script que necesita una cierta versión de Python, por ejemplo 2,7, que cambiaría la primera línea de

#!/bin/env python2.7 

Y luego asegurarse de que python2.7 es en su camino (puede que tenga que añadir enlaces simbólicos, según corresponda). En todas las distribuciones que he usado, estos enlaces simbólicos ya existen.

(De hecho, python es típicamente un enlace simbólico a pythonX que es un enlace a pythonX.Y o, en mi caso, python -> python2 -> python2.7.)

No hay necesidad de codificar una ruta completa, ya que esto puede variar de distribución a la distribución o caja a caja.

Pero como no debería haber ambigüedad para un ejecutable en su ruta llamada python2.7, debería estar bien sin tener que preocuparse por rutas de codificación fija.

Por otra parte, desde el interior de la primera secuencia de comandos, puede llamar al intérprete de Python directamente, como en:

subprocess.Popen(['pythonX.Y', SCRIPT_NAME]) 

en lugar de

subprocess.Popen([SCRIPT_NAME]) 

EDITAR Como JF Sebastián señala en los comentarios, puede usar sys.executable en el primer argumento para asegurarse de que la segunda secuencia de comandos se pasó al mismo intérprete que la primera. por ejemplo

subprocess.Popen([sys.executable, SCRIPT_NAME]) 

Como nota al margen, que puede o puede no ser útil, puede acceder a la versión de la "corriente" intérprete de Python dentro el guión de

import sys 
print(sys.hexversion) 

la que puede ser útil para determinar si el intérprete correcto se está ejecutando.

+0

@jedwards el cierto shebang no funciona, obteniendo un error de ruta no válida en apache – Volatil3

3

Lo que yo haría es cambiar primero el #!/bin/env a la ruta python2.7 directamente, por ejemplo: #!/usr/local/bin/python2.7 funcionará.

En el caso del Sistema A y B son python2.7 trayectoria en diferentes lugares (lo que parece ser su caso) siempre se puede crear un enlace simbólico de esta manera:

ln -s /bin/python2.7 /usr/local/bin/python2.7 

y debería funcionar bien.

2

¿Por qué no utilizar virtualenv? Se le permite utilizar cualquier versión de Python instalado (además de otras cosas) ...

starenka /tmp % virtualenv test -ppython2.6 
Running virtualenv with interpreter /usr/bin/python2.6 
New python executable in test/bin/python2.6 
Also creating executable in test/bin/python 
Installing setuptools............................done. 
Installing pip...............done. 

starenka /tmp % source test/bin/activate 

(test)starenka /tmp % which python 
/tmp/test/bin/python 

(test)starenka /tmp % python --version 
Python 2.6.8 

(test)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test/test.py 

(test)starenka /tmp % chmod +x test/test.py 

(test)starenka /tmp % test/test.py 
(2, 6, 8, 'final', 0) 

starenka /tmp % virtualenv test7 -ppython2.7 
Running virtualenv with interpreter /usr/bin/python2.7 
New python executable in test7/bin/python2.7 
Also creating executable in test7/bin/python 
Installing setuptools............done. 
Installing pip...............done. 
starenka /tmp % source test7/bin/activate 

(test7)starenka /tmp % which python 
/tmp/test7/bin/python 

(test7)starenka /tmp % python --version 
Python 2.7.3rc2 

(test7)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test7/test.py 

(test7)starenka /tmp % chmod +x test7/test.py 

(test7)starenka /tmp % test7/test.py 
sys.version_info(major=2, minor=7, micro=3, releaselevel='candidate', serial=2) 
0

estúpida y simple

En el shell, si es necesario:

ln -s /path/to/your/python2.X /usr/local/bin/python2 

En el pitón secuencia de comandos:

#!/bin/bash 
"exec" "python2" "$0" 

He pasado por este tipo de pro blems, y esta solución resolvió la mayoría de los casos, y se podía transportar fácilmente de un sistema a otro (se podían enfrentar diferentes caminos entre sistemas, diferentes versiones del software ...). Primero crea un enlace simbólico para asegurarte de que ejecutarás la versión correcta de Python (esto es especialmente cierto ahora que nunca lo haces ahora si Python3 es solo Python), y luego confías en el entorno bash. Por lo tanto, no cambia el script cada vez que se dirige a un sistema para un script de utilidad que no requiere la molestia de un paquete.