Je suis dans une situation intéressante où j'ai un script Python qui peut théoriquement être exécuté par une variété d'utilisateurs avec une variété d'environnements (et de CHEMINS) et sur une variété de systèmes Linux. Je veux que ce script soit exécutable sur autant de ceux-ci que possible sans restrictions artificielles. Voici quelques configurations connues:
- Python 2.6 est la version système de Python, donc python, python2 et python2.6 existent tous dans / usr / bin (et sont équivalents).
- Python 2.6 est la version système de Python, comme ci-dessus, mais Python 2.7 est installé à côté d'elle en tant que python2.7.
- Python 2.4 est la version système de Python, que mon script ne prend pas en charge. Dans / usr / bin, nous avons python, python2 et python2.4 qui sont équivalents et python2.5, que le script prend en charge.
Je veux exécuter le même script python exécutable sur ces trois. Ce serait bien s'il essayait d'abord d'utiliser /usr/bin/python2.7, s'il existe, puis de revenir à /usr/bin/python2.6, puis de revenir à /usr/bin/python2.5, puis erreur simplement si aucun d'entre eux n'était présent. Je ne suis pas trop accroché à cela en utilisant la version 2.x la plus récente possible, tant qu'il est capable de trouver l'un des interprètes appropriés s'il est présent.
Ma première inclination a été de changer la ligne de shebang de:
#!/usr/bin/python
à
#!/usr/bin/python2.[5-7]
car cela fonctionne très bien en bash. Mais l'exécution du script donne:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
D'accord, j'essaie donc ce qui suit, qui fonctionne également en bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
Mais encore une fois, cela échoue avec:
/bin/bash: - : invalid option
Bien sûr, je pourrais simplement écrire un script shell séparé qui trouve l'interpréteur correct et exécute le script python à l'aide de l'interpréteur qu'il a trouvé. Je trouverais juste compliqué de distribuer deux fichiers où un devrait suffire tant qu'il est exécuté avec l'interpréteur python 2 le plus récent installé. Demander aux gens d'invoquer explicitement l'interpréteur (par exemple, $ python2.5 script.py
) n'est pas une option. S'appuyer sur le PATH de l'utilisateur en cours de configuration d'une certaine manière n'est pas non plus une option.
Éditer:
La vérification de version dans le script Python ne fonctionnera pas car j'utilise l'instruction "with" qui existe à partir de Python 2.6 (et peut être utilisée dans 2.5 avec from __future__ import with_statement
). Cela provoque l'échec immédiat du script avec une erreur de syntaxe peu conviviale et m'empêche d'avoir la possibilité de vérifier d'abord la version et d'émettre une erreur appropriée.
Exemple: (essayez ceci avec un interpréteur Python inférieur à 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
) Entraînerait l'exécution de python2.4, ce qui entraînerait votre code à détecter qu'il s'agissait de la mauvaise version (et à quitter, probablement). Mais il y a un très bon python2.5 qui aurait pu être utilisé comme interprète à la place!
exec
si c'est le cas, sinon affichez une erreur.
execve
). Les arguments sont des littéraux de chaîne, pas de globalisation, pas de regexps. C'est ça. Même si le premier argument est "/ bin / bash" et les secondes options ("-c ...") ces options ne sont pas analysées par un shell. Ils sont remis non traités à l'exécutable bash, c'est pourquoi vous obtenez ces erreurs. De plus, le shebang ne fonctionne que s'il est au début. Donc, vous n'avez pas de chance ici, je le crains (à court d'un script qui trouve un interprète python et le nourrit d'un document ICI, ce qui ressemble à un désordre horrible).
import sys; sys.version_info()
pour vérifier si l'utilisateur a la version python requise.