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.