web-dev-qa-db-fra.com

Impossible de passer un argument à python avec "#! / Usr / bin / env python"

J'avais besoin d'avoir un script directement exécutable python, alors j'ai commencé le fichier avec #!/usr/bin/env python. Cependant, j'ai également besoin d'une sortie sans tampon, j'ai donc essayé #!/usr/bin/env python -u, mais cela échoue avec python -u: no such file or directory.

J'ai découvert que #/usr/bin/python -u fonctionne, mais j'en ai besoin pour que python dans PATH supporte les environnements virtuels env.

Quelles sont mes options?

68
Eskil

Il est préférable d'utiliser la variable d'environnement pour l'activer. Voir python doc: http://docs.python.org/2/using/cmdline.html

pour votre cas:

export PYTHONUNBUFFERED=1
script.py
22
Larry Cai

Dans certains environnements, env ne divise pas les arguments. Donc, votre env recherche "python -u" sur votre chemin. Nous pouvons utiliser sh pour contourner. Remplacez votre Shebang par les lignes de code suivantes et tout ira bien.

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

p.s. nous n'avons pas à nous soucier du chemin vers sh, non?

40
Ade YU

Lorsque vous utilisez Shebang sous Linux, le reste de la ligne après le nom de l'interpréteur est interprété comme un seul argument. Le python -u est passé à env comme si vous aviez tapé: /usr/bin/env 'python -u'. Le /usr/bin/env recherche un binaire appelé python -u, dont il n'y en a pas.

15
Jimmy Hartzell

Passer des arguments à la ligne Shebang n'est pas standard et, comme vous l'avez expérimenté, ne fonctionne pas en combinaison avec env sous Linux. La solution avec bash consiste à utiliser la commande intégrée "set" pour définir les options requises. Je pense que vous pouvez faire de même pour définir une sortie non tamponnée de stdin avec une commande python.

my2c

13
neuro

Voici une alternative de script à/usr/bin/env, qui permet de passer des arguments sur la ligne de hachage-coup, basé sur/bin/bash et avec la restriction que les espaces sont interdits dans le chemin exécutable. Je l'appelle "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[@]}"

En supposant que ce script se trouve dans/usr/local/bin/envns, voici votre ligne Shebang:

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

Testé sur Ubuntu 13.10 et cygwin x64.

9
philwalk

Cela peut être un peu dépassé mais le manuel env (1) indique que l'on peut utiliser '-S' pour ce cas

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

Il semble fonctionner assez bien sur FreeBSD.

7
user3249132

C'est un kludge et nécessite bash, mais cela fonctionne:

#!/bin/bash

python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
5
imgx64

À partir de la réponse de Larry Cai, env vous permet de définir une variable directement dans la ligne de commande. Cela veut dire que -u peut être remplacé par le paramètre PYTHONUNBUFFERED équivalent avant python:

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

Fonctionne sur RHEL 6.5. Je suis à peu près sûr que la fonctionnalité de env est à peu près universelle.

4
Mad Physicist