it-swarm.it

Come fa / usr / bin / env a sapere quale programma usare?

Quando uso Shebang #!/usr/bin/env python per eseguire uno script, come fa il sistema a sapere quale python usare? se cerco un percorso bin python nelle variabili d'ambiente non trovo nulla.

env | grep -i python
65
tMC

Shebang prevede di utilizzare un percorso completo per l'interprete in modo che la sintassi seguente sia errata:

#!python

L'impostazione di un percorso completo come questo potrebbe funzionare:

#!/usr/local/bin/python

ma non sarebbe portatile come python potrebbe essere installato in /bin, /opt/python/bin o in qualsiasi altra posizione.

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 in PATH.

55
jlliagre

La linea Shebang (da "sharp bang", ovvero #!) viene elaborato dal kernel. Il kernel non vuole conoscere variabili di ambiente come PATH. Quindi il nome sulla linea 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 Python, è possibile specificare

#!/usr/bin/python

sulla prima riga e quando si esegue lo script, il kernel eseguirà effettivamente /usr/bin/python /path/to/script. Ma non è conveniente: devi specificare il percorso completo del comando. Cosa succede se hai python in /usr/bin su alcune macchine e /usr/local/bin su altri? Oppure vuoi impostare PATH su /home/joe/opt/python-2.5/bin in modo da utilizzare una versione specifica di Python? Dato che il kernel non eseguirà la ricerca PATH, l'idea è di far eseguire al kernel un comando che a sua volta cerca l'interprete desiderato in PATH:

#!/fixed/path/to/path-lookup-command python

Quello path-lookup-command deve prendere il nome di un eseguibile come argomento e cercarlo in PATH ed eseguirlo: il kernel eseguirà /fixed/path/to/path-lookup-command python /path/to/script. In effetti, il comando env fa proprio questo. Il suo scopo principale è quello di eseguire un comando con un ambiente diverso, ma poiché cerca il nome del comando in $PATH, è perfetto per il nostro scopo qui.

Sebbene ciò non sia ufficialmente garantito, i sistemi Unix storici hanno fornito env in /usr/bin e i sistemi moderni hanno mantenuto quella posizione proprio a causa dell'uso diffuso di #!/usr/bin/env. Quindi, in pratica, il modo per specificare che uno script deve essere eseguito dal preferito dall'utente Python è

#!/usr/bin/env python

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
7
Dan Rue