Sono in una situazione un po 'interessante in cui ho uno script Python che può teoricamente essere gestito da una varietà di utenti con una varietà di ambienti (e PATH) e su una varietà di sistemi Linux. Voglio che questo script sia eseguibile sul maggior numero possibile di questi senza restrizioni artificiali. Ecco alcune impostazioni note:
- Python 2.6 è la versione di Python del sistema, quindi python, python2 e python2.6 esistono tutti in / usr / bin (e sono equivalenti).
- Python 2.6 è la versione del sistema Python, come sopra, ma Python 2.7 è installato accanto ad esso come python2.7.
- Python 2.4 è la versione del sistema Python, che il mio script non supporta. In / usr / bin abbiamo python, python2 e python2.4 che sono equivalenti e python2.5, che supporta lo script.
Voglio eseguire lo stesso script python eseguibile su tutti e tre questi. Sarebbe bello se tentasse di usare prima /usr/bin/python2.7, se esiste, quindi ripiegare su /usr/bin/python2.6, quindi ripiegare su /usr/bin/python2.5, quindi semplicemente errore se nessuno di quelli era presente. Tuttavia, non sono troppo preso dall'uso della versione 2.x più recente possibile, purché sia in grado di trovare uno degli interpreti corretti, se presente.
La mia prima inclinazione era quella di cambiare la linea di shebang da:
#!/usr/bin/python
per
#!/usr/bin/python2.[5-7]
dal momento che funziona bene in bash. Ma eseguire lo script dà:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
Va bene, quindi provo quanto segue, che funziona anche in bash:
#!/bin/bash -c /usr/bin/python2.[5-7]
Ma ancora una volta, questo non riesce con:
/bin/bash: - : invalid option
Ok, ovviamente potrei semplicemente scrivere uno script shell separato che trova l'interprete corretto ed esegue lo script Python usando qualunque interprete trovato. Troverei una seccatura distribuire due file dove uno dovrebbe bastare purché sia eseguito con l'interprete Python 2 più aggiornato installato. Chiedere alle persone di invocare esplicitamente l'interprete (ad es. $ python2.5 script.py
) Non è un'opzione. Fare affidamento sul PERCORSO dell'utente impostato in un determinato modo non è un'opzione.
Modificare:
Il controllo della versione all'interno dello script Python non funzionerà poiché sto usando l'istruzione "with" che esiste a partire da Python 2.6 (e può essere utilizzata in 2.5 con from __future__ import with_statement
). Questo fa sì che lo script fallisca immediatamente con un SyntaxError ostile all'utente e mi impedisce di avere mai l'opportunità di controllare prima la versione ed emettere un errore appropriato.
Esempio: (prova questo con un interprete Python inferiore a 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
) provocherebbe la sua esecuzione da parte di python2.4, facendo sì che il tuo codice rilevi che era la versione sbagliata (ed esce, presumibilmente). Ma c'è un python2.5 perfettamente valido che avrebbe potuto essere usato come interprete!
exec
, in tal caso, stampare un errore.
execve
). Gli argomenti sono letterali a stringhe, niente strappi, nessuna regexps. Questo è tutto. Anche se il primo argomento è "/ bin / bash" e le seconde opzioni ("-c ...") tali opzioni non vengono analizzate da una shell. Vengono consegnati non trattati all'eseguibile bash, motivo per cui si ottengono tali errori. Inoltre, lo shebang funziona solo se è all'inizio. Quindi sei sfortunato qui, temo (a corto di una sceneggiatura che trova un interprete Python e lo alimenta un documento QUI, che suona come un disastro terribile).
import sys; sys.version_info()
per verificare se l'utente ha la versione di Python richiesta.