2012-08-15 26 views
21

Tengo un script que quiero que esté disponible globalmente. He empezado con la norma Hashbang:Ejecutar el script de python desde el interior del contenedor virtualenv no funciona

#! /usr/bin/env python 

y vinculado en el directorio bin de mi virtualenv:

~/environments/project/env/bin/myscript 

y ha añadido ese directorio a mi camino. Cuando ejecuto el comando:

myscript 

Aparece un error de importación con una de las bibliotecas. Sin embargo, si activo el entorno virtual y ejecuto el script, funciona como se esperaba.

He descartado un problema con el enlace simbólico (también intenté simplemente mover el script dentro de la carpeta bin). También he intentado ejecutar el script con el pitón

python ~/environments/project/env/bin/myscript 

Anteriormente yo estaba usando un script que activa el medio ambiente y luego corrió mi guión, pero yo tenía la impresión de que la secuencia de comandos ejecutada desde esta carpeta debe correr con los de virtualenv intérprete y paquetes de sitios. ¿Alguna idea de por qué esto podría no estar funcionando o de alguna manera podría depurar esto?

+1

No relacionado con su pregunta: aunque la mayoría de las conchas lo ignoran, ¡usando '#!/'es estrictamente incorrecto, ya que el espacio debe considerarse parte del camino del programa. Suelta el espacio y estás a salvo. – kay

Respuesta

35

Poner la secuencia de comandos en la bandeja de su Virtualenv, y luego agregar esa ubicación bin a su PATH global no se fuente automáticamente su Virtualenv. Primero debe obtenerlo para activarlo.

Todo lo que su sistema sabe es comprobar esa ruta adicional para el ejecutable y ejecutarlo. No hay nada en ese script que indique un virtualenv.

Se podría, sin embargo, codificar la línea de ella-bang a su pitón virtualenv, en cuyo caso los site-packages terminarán en el camino:

#!/Users/foo/environments/project/env/bin/python 

U otra opción es crear simplemente una pequeña envoltorio fiesta que llama a la secuencia de comandos pitones original, lo que le permitirá salir de su guión original con un genérico ella-bang ..

Así que si myscript.py es: #!/usr/bin/env python ...

entonces puede presentar una myscript:

#!/bin/bash 

/Users/foo/environments/project/env/bin/python myscript.py 

Al hacer myscript, se llamará de forma explícita la secuencia de comandos de Python con el intérprete de configurar.

+0

Gracias, eso es lo que hizo mi script original. Tenía un recuerdo de haber visto algo que pensé que dicha carpeta activaría el entorno, pero estás en lo cierto al reflexionar, veo que sería imposible. – justin

7

Creo que no está seguro de cómo funciona virtualenv.

En pocas palabras, virtualenv modifica su entorno de shell para que Python busque en diferentes áreas los módulos que desea importar. Realmente no hay ninguna relación entre dónde almacena su entorno virtual y dónde almacena sus archivos fuente que ejecuta en el virtualenv. Si quisiera, podría almacenar su virtualenv en un directorio llamado ~/environments/my_env, y toda la fuente que codifique mientras usa su virtualenv en ~/projects/my_proj.

Puede leer más sobre what virtulenv does en los documentos.

Realmente, lo único que le dice a python dónde encontrar los módulos está completamente basado en python (see the docs sobre cómo funciona). Activar un virtualenv cambia la forma en que funciona Python.

Puede volver a tener un script de shell para activar virtualenv, o puede seguir this recipe para activarlo directamente desde su script.

activate_this = '/path/to/env/bin/activate_this.py' 
execfile(activate_this, dict(__file__=activate_this)) 

Si elige esta ruta, mantener la información de los documentos dan en mente:

Esto cambiará sys.path e incluso cambiar sys.prefix, sino que también permiten el uso de un existente Interprete. Los elementos en su entorno se mostrarán primero en en sys.path, antes de los elementos globales. Sin embargo, siempre se podrá acceder a los elementos globales (como si el indicador --system-site-packages tuviera utilizado para crear el entorno, ya sea o no). Además, esto no puede deshacer la activación de otros entornos, o módulos que han sido importados. No debe intentar, por ejemplo, activar un entorno antes de una solicitud web; debe activar un entorno lo antes posible y no volver a hacerlo en ese proceso.

0

Me enfrenté al mismo problema y se me ocurrió esta solución: https://github.com/jabbalaci/wpython. Es un script llamado "wpython" que llama a su programa con el intérprete local de Python en su entorno. Por lo tanto, en lugar de "/Users/foo/environments/project/env/bin/python myscript.py" es suficiente escribir "wpython /path/to/myscript.py". Un script de iniciador podría verse así:

#!/usr/bin/env bash 

cd /the/directory/where/myscript.py/is/located 
wpython myscript.py 
2

¿No podría simplemente agregar una ruta relativa en su lugar? Esto funcionó para mí:

#!./env/bin/python 
0

En caso de que esté utilizando Windows, puede incluir la siguiente línea en la parte superior del archivo de Python.

#! P:\Workspace\pythontut\Scripts python 
Cuestiones relacionadas