msi installed python arguments shebang

installed - python windows



No se puede pasar un argumento a python con "#!/Usr/bin/env python" (9)

Necesitaba tener un script python directamente ejecutable, así que comencé el archivo con #!/usr/bin/env python . Sin embargo, también necesito salida sin búfer, así que probé #!/usr/bin/env python -u , pero eso falla con python -u: no such file or directory .

Descubrí que #/usr/bin/python -u funciona, pero necesito que python en PATH compatible con entornos virtuales de env .

¿Cuáles son mis opciones?


Aquí hay una alternativa de script a / usr / bin / env, que permite pasar argumentos en la línea hash-bang, basada en / bin / bash y con la restricción de que los espacios no están permitidos en la ruta ejecutable. Lo llamo "envns" (env No Spaces):

#!/bin/bash ARGS=( $1 ) # separate $1 into multiple space-delimited arguments. shift # consume $1 PROG=`which ${ARGS[0]}` unset ARGS[0] # discard executable name ARGS+=( "$@" ) # remainder of arguments preserved "as-is". exec $PROG "${ARGS[@]}"

Suponiendo que este script se encuentre en / usr / local / bin / envns, aquí está su línea de shebang:

#!/usr/local/bin/envns python -u

Probado en Ubuntu 13.10 y cygwin x64.


Cuando usa shebang en Linux, todo el resto de la línea después del nombre del intérprete se interpreta como un único argumento. La python -u pasa a env como si hubiera escrito: /usr/bin/env ''python -u'' . El /usr/bin/env busca un binario llamado python -u , que no es uno.


En algún entorno, env no divide los argumentos. Entonces su env está buscando "python -u" en su camino. Podemos usar sh para evitarlo. Reemplace su shebang con las siguientes líneas de código y todo estará bien.

#!/bin/sh ''''''''exec python -u -- "$0" ${1+"$@"} # '''''' # vi: syntax=python

ps no tenemos que preocuparnos por el camino a sh, ¿verdad?



Esto es un kludge y requiere bash, pero funciona:

#!/bin/bash python -u <(cat <<"EOF" # Your script here print "Hello world" EOF )


Esto podría estar un poco desactualizado pero el manual de env (1) dice que uno puede usar ''-S'' para ese caso

#!/usr/bin/env -S python -u

Parece funcionar bastante bien en FreeBSD.


Partiendo de la respuesta de Larry Cai, env permite establecer una variable directamente en la línea de comando. Eso significa que -u puede ser reemplazado por la configuración PYTHONUNBUFFERED equivalente antes de python :

#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python

Funciona en RHEL 6.5. Estoy bastante seguro de que la característica de env es casi universal.


Pasar argumentos a la línea shebang no es estándar y, como lo ha experimentado, no funciona en combinación con env en Linux. La solución con bash es usar el comando integrado "set" para establecer las opciones requeridas. Creo que puede hacer lo mismo para establecer la salida de búfer de stdin con un comando de python.

my2c


Recientemente escribí un parche para la versión GNU Coreutils de env para abordar este problema:

http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html

Si tiene esto, puede hacer:

#!/usr/bin/env :lang:--foo:bar

env se dividirá :lang:foo:--bar en los campos lang , foo y --bar . --foo PATH el intérprete lang , y luego lo invocará con argumentos --foo , bar , más la ruta al guión y los argumentos del guión.

También hay una función para pasar el nombre del script en el medio de las opciones. Supongamos que desea ejecutar lang -f <thecriptname> other-arg , seguido de los argumentos restantes. Con este env patched, se hace así:

#!/usr/bin/env :lang:-f:{}:other-arg

El campo más a la izquierda que es equivalente a {} se reemplaza con el primer argumento que sigue, que, bajo la invocación de hash bang, es el nombre del script. Ese argumento luego se elimina.

Aquí, other-arg podría ser algo procesado por lang o quizás algo procesado por el script.

Para comprender mejor, vea los numerosos casos de prueba de echo en el parche.

Elegí el carácter : porque es un separador existente utilizado en los sistemas PATH en POSIX. Como env realiza la búsqueda PATH , es muy poco probable que se use para un programa cuyo nombre contiene dos puntos. El marcador {} proviene de la utilidad de find , que lo usa para denotar la inserción de una ruta en la línea de comando -exec .