Estou em uma situação um pouco interessante, onde tenho um script Python que teoricamente pode ser executado por uma variedade de usuários com uma variedade de ambientes (e PATHs) e em uma variedade de sistemas Linux. Quero que esse script seja executável no maior número possível, sem restrições artificiais. Aqui estão algumas configurações conhecidas:
- Python 2.6 é a versão do sistema em Python, portanto, python, python2 e python2.6 existem em / usr / bin (e são equivalentes).
- Python 2.6 é a versão do sistema Python, como acima, mas o Python 2.7 é instalado ao lado dele como python2.7.
- Python 2.4 é a versão do sistema Python, que meu script não suporta. Em / usr / bin, temos python, python2 e python2.4, que são equivalentes, e python2.5, que o script suporta.
Eu quero executar o mesmo script python executável em todos os três. Seria bom se ele tentasse usar o /usr/bin/python2.7 primeiro, se existir, volte para /usr/bin/python2.6 e depois para /usr/bin/python2.5, depois simplesmente erro se nenhum deles estiver presente. Não estou muito empolgado com isso usando o 2.x mais recente possível, desde que seja capaz de encontrar um dos intérpretes corretos, se presente.
Minha primeira inclinação foi mudar a linha shebang de:
#!/usr/bin/python
para
#!/usr/bin/python2.[5-7]
pois isso funciona bem no bash. Mas a execução do script fornece:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
Ok, então eu tento o seguinte, que também funciona no bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
Mas, novamente, isso falha com:
/bin/bash: - : invalid option
Ok, obviamente eu poderia escrever um script de shell separado que encontre o intérprete correto e execute o script python usando o interpretador encontrado. Eu consideraria um incômodo distribuir dois arquivos onde um seria suficiente, desde que seja executado com o intérprete python 2 mais atualizado instalado. Pedir às pessoas que invoquem o intérprete explicitamente (por exemplo, $ python2.5 script.py) não é uma opção. Confiar no PATH do usuário sendo configurado de uma certa maneira também não é uma opção.
Editar:
A verificação de versão no script Python não funcionará, pois estou usando a instrução "with" que existe no Python 2.6 (e pode ser usada no 2.5 com from __future__ import with_statement). Isso faz com que o script falhe imediatamente com um SyntaxError hostil ao usuário e me impede de ter a oportunidade de verificar a versão primeiro e emitir um erro apropriado.
Exemplo: (tente isso com um interpretador Python menor que 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) faria com que o python2.4 o executasse, o que faria com que o seu código detetasse que era a versão errada (e saia, presumivelmente). Mas há um python2.5 perfeitamente bom que poderia ter sido usado como intérprete!
exec, se houver, imprima um erro.
execve). Os argumentos são literais de string, sem globbing, sem regexps. É isso aí. Mesmo se o primeiro argumento for "/ bin / bash" e a segunda opção ("-c ..."), essas opções não serão analisadas por um shell. Eles são entregues sem tratamento para o executável do bash, e é por isso que você obtém esses erros. Além disso, o shebang só funciona se for no começo. Acho que você está sem sorte aqui (com exceção de um script que encontra um interpretador python e o alimenta com um documento HERE, que soa como uma bagunça terrível).
import sys; sys.version_info()para verificar se o usuário tem a versão python necessária.