Estoy en una situación interesante en la que tengo un script de Python que teóricamente puede ser ejecutado por una variedad de usuarios con una variedad de entornos (y PATHs) y en una variedad de sistemas Linux. Quiero que este script sea ejecutable en la mayor cantidad posible sin restricciones artificiales. Aquí hay algunas configuraciones conocidas:
- Python 2.6 es la versión de Python del sistema, por lo que python, python2 y python2.6 existen en / usr / bin (y son equivalentes).
- Python 2.6 es la versión de Python del sistema, como se indicó anteriormente, pero Python 2.7 está instalado junto a ella como python2.7.
- Python 2.4 es la versión de Python del sistema, que mi script no admite. En / usr / bin tenemos python, python2 y python2.4 que son equivalentes, y python2.5, que admite el script.
Quiero ejecutar el mismo script ejecutable de Python en estos tres. Sería bueno si intentara usar /usr/bin/python2.7 primero, si existe, luego volver a /usr/bin/python2.6, luego volver a /usr/bin/python2.5, luego simplemente error si ninguno de esos estaba presente. Sin embargo, no estoy demasiado obsesionado con el 2.x más reciente posible, siempre que pueda encontrar uno de los intérpretes correctos si está presente.
Mi primera inclinación fue cambiar la línea shebang de:
#!/usr/bin/python
a
#!/usr/bin/python2.[5-7]
ya que esto funciona bien en bash. Pero ejecutar el script da:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
Bien, entonces intento lo siguiente, que también funciona en bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
Pero de nuevo, esto falla con:
/bin/bash: - : invalid option
De acuerdo, obviamente podría escribir un script de shell separado que encuentre el intérprete correcto y ejecute el script de Python usando el intérprete que encuentre. Simplemente me resultaría una molestia distribuir dos archivos donde uno debería ser suficiente siempre que se ejecute con el intérprete de Python 2 más actualizado instalado. Pedirle a la gente que invoque al intérprete explícitamente (p. Ej. $ python2.5 script.py
) No es una opción. Confiar en que la RUTA del usuario se configure de cierta manera tampoco es una opción.
Editar:
La verificación de versiones dentro del script Python no funcionará ya que estoy usando la instrucción "con" que existe a partir de Python 2.6 (y se puede usar en 2.5 con from __future__ import with_statement
). Esto hace que el script falle inmediatamente con un SyntaxError hostil para el usuario, y me impide tener la oportunidad de verificar primero la versión y emitir un error apropiado.
Ejemplo: (intente esto con un intérprete de Python menor que 2.6)
#!/usr/bin/env python
import sys
print "You'll never see this!"
sys.exit()
with open('/dev/null', 'w') as out:
out.write('something')
./script.py
) causaría que python2.4 lo ejecute, lo que haría que su código detecte que se trata de una versión incorrecta (y que se cierre, presumiblemente). ¡Pero hay un python2.5 perfectamente bueno que podría haber sido utilizado como intérprete!
exec
, de ser así, imprima un error.
execve
). Los argumentos son literales de cadena, sin globalización, sin expresiones regulares. Eso es. Incluso si el primer argumento es "/ bin / bash" y las segundas opciones ("-c ...") esas opciones no son analizadas por un shell. Se entregan sin tratar al ejecutable de bash, por lo que obtienes esos errores. Además, el shebang solo funciona si está al principio. Entonces, no tienes suerte aquí, me temo (a falta de un script que encuentre un intérprete de Python y lo alimente con un documento AQUÍ, que suena como un desastre horrible).
import sys; sys.version_info()
para verificar si el usuario tiene la versión de Python requerida.