Quando uso Shebang #!/usr/bin/env python
per eseguire uno script, come fa il sistema a sapere quale python
utilizzare? se cerco un python
percorso bin nelle variabili d'ambiente non trovo nulla.
env | grep -i python
Quando uso Shebang #!/usr/bin/env python
per eseguire uno script, come fa il sistema a sapere quale python
utilizzare? se cerco un python
percorso bin nelle variabili d'ambiente non trovo nulla.
env | grep -i python
Risposte:
Shebang si aspetta che venga utilizzato un percorso completo per l'interprete, pertanto la sintassi seguente non sarebbe corretta:
#!python
L'impostazione di un percorso completo come questo potrebbe funzionare:
#!/usr/local/bin/python
ma sarebbe non portatile come pitone potrebbe essere installato in /bin
, /opt/python/bin
, o dovunque altro luogo.
utilizzando env
#!/usr/bin/env python
è un metodo che consente in modo portatile di specificare al sistema operativo un percorso completo equivalente a quello in cui python
si trova per la prima volta nel file PATH
.
La linea shebang (da "sharp bang", cioè #!
) viene elaborata dal kernel. Il kernel non vuole conoscere variabili di ambiente come PATH
. Quindi il nome sulla riga shebang deve essere un percorso assoluto per un eseguibile. Puoi anche specificare un argomento aggiuntivo da passare a quell'eseguibile prima del nome dello script (con restrizioni dipendenti dal sistema che non entrerò qui). Ad esempio, per uno script Python, è possibile specificare
#!/usr/bin/python
sulla prima riga e quando si esegue lo script, il kernel verrà effettivamente eseguito /usr/bin/python /path/to/script
. Ma non è conveniente: devi specificare il percorso completo del comando. Cosa fare se avete python
in /usr/bin
su alcune macchine e /usr/local/bin
sugli altri? O vuoi impostarlo PATH
su in /home/joe/opt/python-2.5/bin
modo da utilizzare una versione specifica di Python? Dato che il kernel non farà la PATH
ricerca per te, l'idea è di far eseguire al kernel un comando che a sua volta cerca l'interprete desiderato nel PATH
:
#!/fixed/path/to/path-lookup-command python
Questo path-lookup-command
deve prendere il nome di un eseguibile come argomento e cercarlo PATH
ed eseguirlo: il kernel verrà eseguito /fixed/path/to/path-lookup-command python /path/to/script
. Come succede, il env
comando fa proprio questo. Il suo scopo principale è quello di eseguire un comando con un ambiente diverso, ma poiché cerca il nome del comando $PATH
, qui è perfetto per il nostro scopo.
Anche se questo non è ufficialmente garantita, i sistemi Unix storici forniti env
in /usr/bin
, e sistemi moderni hanno mantenuto quella posizione proprio per l'uso diffuso di #!/usr/bin/env
. Quindi, in pratica, il modo per specificare che uno script deve essere eseguito dall'interprete Python preferito dall'utente è
#!/usr/bin/env python
env
e which
? da cui otterrò anche l'eseguibile più idoneo dal mio ambiente PATH.
which
trova l'eseguibile e stampa il suo percorso. env
trova il programma specificato dal primo argomento e lo esegue, passando gli argomenti rimanenti.
env
una versione negativa di which
essenzialmente.
Bene, quindi corri:
env | grep PATH
$ PATH è un elenco di directory. Unix passerà attraverso quell'elenco di directory, in ordine, fino a quando non troverà "Python".
Puoi vedere quale directory trova con il comando 'which':
which python
sys.path
tra un attivato env $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) e ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
).