2010-02-27 25 views
8

Digamos que tenemos un script de Python do.py y queremos poder llamarlo sin extensión, como do o ./do.Cómo ejecutar una secuencia de comandos python sin especificar la extensión de archivo (solución multiplataforma)?

Si cambiamos el nombre del archivo de do.py a do y aseguramos que tenemos una línea de shebang válida, funcionará para todas las plataformas excepto para Windows. En Windows no hay forma de ejecutar el archivo sin extensión.

En Windows, si conservamos la extensión de archivo original, podremos llamar al script sin el nombre completo porque el instalador de Python registra la extensión .py como ejecutable.

Parece que tenemos que entregar la misma secuencia de comandos bajo dos nombres diferentes para llamarlo en entornos Windows y que no sean de Windows. Realmente no me gusta esto y estoy buscando una solución sin esta redundancia.

Otro enfoque común en esto es agregar un archivo por lotes contenedor do.cmd que llama al archivo original do.py. Esto tiene por lo menos un problema importante: lo hace romper el Ctrl + C/Ctrl + INTER porque no hay manera de prevenir cmd.exe de instándole con Terminate batch job? (Y/N) message.

Si vamos a utilizar un envoltorio que tenemos que ser Asegúrese de que:

  • retorno del código de error (nivel de error) devuelto por el guión original
  • no va a cambiar el entorno
  • va a volver a utilizar la misma consola (no hay ventanas nuevas)
  • no interfiere con la salida estándar, STDIN o STDERR
  • ser amigable con Ctrl-C (no hay indicaciones)

supongo que la solución óptima es todavía utilizar un envoltorio. Batch no funcionará, el ejecutable nativo agregaría mucha complejidad, por lo que probablemente un wrapper escrito en python haría lo mismo.

+0

La respuesta puede ser la pregunta "¿por qué quieres llamar sin extensión?" –

+0

Wow, qué mucho trabajo sin ningún beneficio real. ¿Qué pasa con do.py? Eso es perfectamente multiplataforma sin ningún trabajo. –

+7

Para aquellos que se preguntan: sin extensión significa que ocultamos los detalles de implementación: por ejemplo, si el próximo año quiero reemplazar la secuencia de comandos de Python actual con una secuencia de comandos de Ruby, no quiero tener que cambiar todas las llamadas al script. Otro argumento menos importante: menos para escribir desde la línea de comandos. – sorin

Respuesta

2

Hasta ahora se me ocurrió esta solución que parece funcionar.Crear un archivo yourname.py con este contenido:

import os, sys 
filename = os.path.splitext(os.path.basename(sys.argv[0]))[0] 
if not os.path.exists(filename): 
    # filename does not exists, we will emulate cmd behaviour 
    sys.stderr.write("'%s' is not recognized as an internal or external command,\noperable program or batch file." % filename) 
    sys.exit(9009) 
ret = os.system("python %s %s" % (
     filename, 
     " ".join(sys.argv[1:]) 
     )) 
exit(ret) 
+0

Relacionado: [Windows - ejecutar .py directamente frente a ejecutar python blah.py se comporta de forma diferente] (http://stackoverflow.com/q/7104920/) –

0

siempre puede llamar a su script con el intérprete de Python. Obtienes la misma consistencia en * nix, cuando usas el intérprete.

de Windows

c:\> python c:\path\to\myscript 

* nix

$ python /path/to/myscript 

Si no es lo que quieres, entonces estoy mal interpretando su pregunta.

+1

Eso no es lo que él quiere. Quiere ejecutarlo como cualquier otro ejecutable en el sistema, sin especificar nada más que el nombre del ejecutable (script) en la línea de comando. –

1

Puede usar distutils para instalar scripts en la instalación de Python (la herramienta easy_install se instala así, por ejemplo).

Para Windows, puede usar py2exe para crear una secuencia de comandos que se puede ejecutar sin la extensión de archivo. En Linux, simplemente puede usar un archivo sin extensión, pero que incluye una línea shebang.

+0

Si instala el script, puede ejecutarlo con 'python -m moduleName'. Eso es multiplataforma, también. –

5

En las ventanas i añade la extensión '.py' a la variable de entorno 'PATHEXT' y que funciona para mí - si el archivo .py se almacena en un directorio que es parte de la variable de entorno 'PATH'.

C:\>echo %PATHEXT% 
.COM;.EXE;.BAT;.CMD;.PY;.JS;.JSE 
+0

Esto funcionó para mí en shells de comandos pero para el prompt de ejecución tuve que agregar una clave "python_script.exe" falsa para el registro - HKLM \ Software \ Microsoft \ Windows \ CurrentVersion \ App Paths \ Luego establecí el valor predeterminado en mi ruta python_script.py y luego pude simplemente escribir "python_script" en el Ejecutar solicitud. –

+0

Pero, ¿cómo funciona esto también en dispositivos que no son de Windows? ¿Puedo escribir 'do' sin la extensión? – Hugo

4

Escribe tu módulo principal Python con una extensión .py. Configure PATHEXT correctamente y se ejecutará en Windows sin tener que escribir la extensión.

En Unix, escriba un segundo programa de Python que simplemente importe el primero, utilizando la sintaxis she-bang. No hay extensión en este archivo, es un script de shell. De esta manera:

#!/usr/bin/env python 
import do 

Esto tendrá el efecto de importación do.py.

Solo do debe marcarse como ejecutable para Unix. do.py es un módulo en ese entorno.

Al importar un módulo, el código en el módulo se ejecuta una vez.

No elimina por completo la redundancia, pero está cerca. Y es probablemente la mejor solución posible para scripting multiplataforma.

+1

Es una solución simétrica a la dada por OP, pero es más simple, así parece ser mejor. –

0

Jason's answer es más clara y sencilla, pero una versión genérica obtiene el nombre del módulo del nombre de archivo:

#!/usr/bin/env python 
import importlib, os, sys 
importlib.import_module(os.path.basename(sys.argv[0])) 

Una vez dicho esto, yo prefiero Jason de donde es inmediatamente claro lo que está pasando:

#!/usr/bin/env python 
import do 
Cuestiones relacionadas