Perché Python in Linux richiede la riga #! / usr / bin / python?

50

Domanda abbastanza semplice: in Linux, perché Python richiede la linea

#!/usr/bin/python

all'inizio di un file python, dal momento che Windows non lo fa?

Che cosa fa? perché la descrizione "Collegamenti a Python" è un po 'vaga ...

    
posta DevRobot 04.11.2015 - 22:48

7 risposte

56

Python non ha alcun requisito speciale su Linux. È il programma loader su Unix / Linux che usa la linea "shebang", come viene chiamata. Questa è in realtà una caratteristica piuttosto che una limitazione, ma ci arriveremo in un momento. La pagina Wiki su "shebang" ha più dettagli, ma proverò a dare anche una panoramica come un confronto con Windows qui.

Per prima cosa, diamo un'occhiata alla situazione su Windows:

  • Quando tenti di aprire o eseguire un file, Windows esamina prima l'estensione di quel file. Questa è la ultima parte del nome file che inizia con . Nel caso di file Python, questo è in genere .py .
  • Windows cerca le azioni da intraprendere in base all'estensione del file.
    • Questa informazione è registrata nel registro di Windows; quando Python è installato, in genere indica a Windows che i file .py devono essere aperti utilizzando la applicazione Python appena installata (vale a dire l'interprete Python).
    • Diversi tipi di file hanno comportamenti integrati; ad esempio, i file eseguibili (come lo stesso interprete Python) devono terminare in .exe e i file .bat vengono eseguiti come script batch di Windows.
    • L'azione intrapresa per un particolare tipo di file è personalizzabile . Ad esempio, puoi dire a Windows che invece di eseguire .py file usando python.exe , dovrebbe aprirli con qualche altro programma, come l'editor di testo notepad.exe .
      • In questo caso, per eseguire uno script Python, dovrai manualmente chiamare python <scriptname>.py (o scrivere un file .bat per fare questo per voi).

Ora, cosa succede se c'è una linea shebang ( #!/usr/bin/python o #!/usr/bin/env python ) nella parte superiore dello script Python? Bene, dato che # è una riga di commento in Python, l'interprete Python lo ignora. Questo è uno dei motivi per cui la maggior parte dei linguaggi di scripting utilizzati nel mondo Unix / Linux usa # per iniziare le righe di commento.

Quindi è un po 'fuorviante dire che Windows "non ha bisogno" della riga #! ; Windows non vede la riga #! , e di fatto si affida all'estensione del file per dirgli cosa fare. Questo ha un paio di svantaggi:

  • Devi devi nominare gli script Python con .py alla fine per farli riconoscere automaticamente come tali.
  • Non esiste un modo semplice per distinguere gli script Python2 dagli script Python3.
  • Come notato in precedenza, se si modifica il comportamento di avvio predefinito per il tipo di file .py , Windows non eseguirà più automaticamente tali script con Python. Nota che questo potrebbe essere fatto involontariamente.

Ora, diamo un'occhiata a come Unix / Linux lancia gli script:

La prima cosa da notare è che Unix / Linux, a differenza di Windows, non sta tentando di "aprire" gli script Python usando un particolare programma, almeno concettualmente; il sistema operativo sa che lo script è qualcosa che può essere eseguito a causa di qualcosa chiamato "bit execute" (che è al di fuori dello scopo di questa risposta). Pertanto, se digiti accidentalmente #!/usr/bin/pthon anziché #!/usr/bin/python , riceverai un messaggio di errore che include questo testo:

/usr/bin/pthon: bad interpreter: No such file or directory.

La parola "interprete" ci dà un indizio sul ruolo della linea shebang (sebbene tecnicamente il programma specificato possa essere qualcosa di diverso da un interprete, come cat o un editor di testo). Quando tenti di eseguire un file, ecco cosa succede:

  • Il programma di caricamento Unix / Linux esamina i primi due byte di quel file; se questi due byte sono #! , il loader interpreta il resto della riga shebang (escluso lo shebang stesso) come comando per avviare un interprete con cui eseguire il contenuto del file come script.
  • Il programma di caricamento lancia l'interprete specificato, alimentandolo come argomento percorso del file originale.

Questo ha un paio di vantaggi:

  • Lo script-writer ha più controllo su quale interprete verrà usato (che risolve il problema Python2 / Python3) e può a volte passare un argomento extra all'interprete (vedere la pagina Wiki per i dettagli).
  • Il nome file dello script è ignorato , quindi puoi dare un nome agli script Python come vuoi.

Nota, infine, che Unix / Linux non ha bisogno della linea shebang per eseguire uno script Python. Ricorda che tutta la linea shebang in realtà fa è consentire al programma di caricamento di selezionare un interprete. Ma proprio come in Windows, questo può essere fatto manualmente:

python <myscript>
    
risposta data Kyle Strand 05.11.2015 - 23:25
41

La linea che hai indicato è usata per dire al computer quale programma / interprete usare quando si esegue direttamente il file / lo script, e qualsiasi argomento che dovrebbe essere passato a quel programma quando viene eseguito lo script. Questo non è, tuttavia, un requisito di Python , è un requisito del kernel / sistema linux se si intende eseguire direttamente lo script (e non passarlo a Python con la seguente sintassi).

Non è necessario se hai intenzione di eseguire python script.py o simili. È necessario solo se si intende eseguire direttamente lo script / file, senza fornire anche l'interprete da utilizzare (come python ).

Per uno script Bash, avrebbe qualcosa di simile a questo:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

Questo indica al sistema che, quando è in esecuzione, dovrebbe essere eseguito tramite /bin/bash , che è uno dei linguaggi shell / shell-script sul sistema.

Per il codice Python, però, qui vorrai che il file eseguibile venga eseguito tramite Python, in modo che tu dica quale interprete hai intenzione di eseguire in esso.

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

Questo, come per Bash, indica che dovrebbe essere usato /usr/bin/python (questo è probabilmente Python 2 o Python 3, a seconda delle singole configurazioni di sistema).

In questo modo, puoi eseguire ./filename.py o ./executable o ./scripttorun direttamente.

Senza questa linea all'inizio e assumendo che tu abbia impostato il file / script per essere eseguibile, e supponendo che tu stia lavorando con uno script Python, dovresti eseguire python filename.py o simile se non avessi il #!/usr/bin/python linea. (Per uno script Bash, dovresti fare bash script.sh , o simile per altri script / linguaggi, come Perl, Ruby, ecc.)

L'evidenziazione della sintassi sopra riportata è specifica della lingua in ogni sezione, anche se non ha molta importanza.

    
risposta data Thomas Ward 04.11.2015 - 22:53
16

La linea:

#!/usr/bin/python

è chiamato 'shebang' e indica il percorso del file binario dell'interprete che verrà utilizzato per interpretare il resto dei comandi nel file. Di solito è la prima riga di uno script.

Quindi la riga #!/usr/bin/python indica che il contenuto del file sarà interpretato dal python binario situato in /usr/bin/python .

Si noti che la riga shebang viene analizzata dal kernel e quindi lo script verrà chiamato come argomento:

python script_name

Analogamente in #!/bin/bash :

bash script_name
    
risposta data heemayl 04.11.2015 - 22:57
7

Tecnicamente, non lo richiede. Richiede un percorso per l'ambiente in cui viene eseguito lo script. I tuoi futuri script farebbero meglio a includere / usr / bin / env, quindi specifica python. Questo garantisce che lo script venga eseguito nell'ambiente python, indipendentemente da dove Python sia installato. Se vuoi farlo per ragioni di compatibilità, non puoi essere sicuro che la prossima persona con cui condividi il tuo codice avrà python installato in usr / bin / python, o che avranno i permessi su quei file di sistema.

Ecco un Q & amp; A simile dallo stack overflow .

Ciò che appare nel tuo script è:

#!/usr/bin/env python

Vedo anche qualche preoccupazione su come specificare python3. Ecco come farlo:

#!/usr/bin/env python3
    
risposta data j0h 05.11.2015 - 17:50
5

In Linux, Python può o non può richiedere la riga #! (shebang). Questo dipende da come vengono gestiti i codici Python, eseguendo i codici in modalità interattiva Python o in uno script Python.

La modalità interattiva Python consente all'utente di digitare ed eseguire direttamente i codici Python, che non richiede la riga shebang. Per eseguire la modalità interattiva, apri un Terminale e digita python per Python 2.X o python3 per Python 3.X.

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Lo script Python consente all'utente di scrivere e salvare i codici Python in un file di testo semplice, quindi eseguire i codici in seguito. Questo può o non può richiedere la linea dello shebang. Tuttavia, ci sono due motivi noti quando è richiesta la riga shebang per usare lo script Python in Linux.

  1. per eseguire i codici Python in uno script eseguibile, cioè definisce come devono essere eseguiti i codici e usando quale interprete;

  2. per eseguire i codici Python rispetto alla versione specifica di Python i.e. codici di esecuzione compatibili con Python 2.X o Python 3.X solo

Esercitati con gli script Python

Di seguito sono riportati l'elenco e il contenuto dei file, che ho utilizzato per mostrare i casi in cui è richiesta o meno la riga #! (shebang).

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py contiene solo il codice sorgente.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py contiene il codice sorgente e la riga shebang.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py contiene lo stesso di hello2.py e reso eseguibile.

  • hello3.py contiene lo stesso di hello2.py , eccetto che è adatto all'esecuzione con Python 3 rinominando la prima riga in #!/usr/bin/env python3 .

  • hello3e.py contiene lo stesso di hello3.py e reso eseguibile.

  • hello3m.py contiene lo stesso di hello3.py e reso eseguibile, eccetto il salvataggio con l'opzione Write Unicode BOM nell'editor di testi, ad es. Mousepad.

Oltre questo punto, all'utente verranno presentati due metodi per eseguire gli script Python. Entrambi i metodi sono stati dimostrati come segue.

Metodo 1: Esegui con il programma Python

Di seguito sono riportati i comandi e l'output quando si esegue il codice sorgente con Python 2 e Python 3.

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Entrambe le versioni di Python erano in grado di eseguire correttamente lo script. Quindi, la riga shebang è non richiesta quando si esegue lo script Python tramite python o python3 comando.

Metodo 2: Esegui come script Python

Di seguito sono riportati i comandi e l'output quando si esegue il codice sorgente con la riga shebang, che non si adatta a nessuno dei due, Python 2 e Python 3, inclusi casi non eseguibili ed eseguibili.

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

I primi tre script non sono riusciti perché questi script non sono eseguibili, indipendentemente dal fatto che la riga di shebang sia o meno (per la prova di supporto, vedi Esempio aggiuntivo di seguito). Gli ultimi due script hanno una riga shebang e sono eseguibili.

Apparentemente, uno script che è stato reso eseguibile è essenzialmente inutile senza la riga shebang. Quindi, è richiesta la riga shebang e lo script deve essere eseguibile quando si eseguono i codici Python in uno script eseguibile.

Quando shebang non funziona

Nel mio esempio preparato e testato, l'esecuzione di hello3m.py come script eseguibile non è riuscita e ha restituito un errore.

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

Questa è una limitazione nota che shebang non funziona o diventa non valida. Quando un file viene salvato come BOM Unicode (Byte Order Mark), non funzionerà normalmente come uno script Python eseguibile.

Esempio aggiuntivo

Questo esempio aggiuntivo deve essere considerato solo come prova di supporto. L'utente dovrebbe evitare di eseguire questo esempio, sebbene il risultato sia innocuo.

Ho creato un altro file chiamato hello1e.py , che contiene lo stesso hello1.py e reso eseguibile. L'esecuzione di questo script ha restituito un errore di sintassi.

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token '"Hello from Python %s\n"'
./hello1e.py: line 2: 'sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

Quando si esegue questo script, in un primo momento, il cursore del mouse verrà modificato in un segno più e non fa nulla in apparenza. L'errore di sintassi non verrà mostrato fino a quando non avrò fatto clic sulla finestra del desktop o del terminale. Quindi, questo script creerà un file sys nella stessa directory dello script.

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

Il file sys è stato identificato come file PostScript, senza estensione file. Questo file può essere aperto nel visualizzatore di documenti, ad esempio Evince, e il file contiene effettivamente uno screenshot della finestra su cui avevo fatto clic in precedenza. Nella mia esperienza, il file può avere dimensioni pari a pochi Megabyte.

Ancora una volta, è richiesta la riga shebang e lo script deve essere eseguibile quando si esegue lo script Python come script eseguibile. Altrimenti, lo script si comporta in modo anomalo come descritto sopra.

Note aggiuntive

Il termine "reso eseguibile" o "deve essere eseguibile" si riferisce al permesso di eseguire lo script.Questa operazione viene eseguita eseguendo il comando chmod +x FILENAME in Terminale o selezionando l'opzione "Consenti a questo file di essere eseguito come programma" o qualcosa di simile nella finestra Proprietà , all'interno di un file manager.

Mentre altre risposte esistenti coprivano quasi tutto, questa risposta ha avuto un approccio diverso utilizzando esempi pratici per spiegare la questione. La sintassi del codice è stata scritta con cura, in modo che gli esempi possano essere eseguiti con Python 2 o Python 3, così com'è.

I codici Python sono stati adattati da Uso di Python su Windows e Utilizzo di Python su piattaforme Unix , con un ulteriore codice a una riga dell'onnipresente "Hello, World!" programma.

Tutti i codici e i comandi sono stati completamente testati e funzionano con il sistema Xubuntu 14.04, che ha installato Python 2.7 e Python 3.4 per impostazione predefinita.

    
risposta data clearkimura 14.12.2015 - 19:19
4

Significa che quando viene eseguito quel file il tuo computer sa di eseguirlo con il programma /usr/bin/python , questo è il modo in cui lo distingui da un'altra lingua, come bash dove dovresti fare #!/bin/bash . Questo è così che puoi semplicemente eseguire:

./[file-to-execute]

E saprà con quale file eseguirlo, piuttosto che tu stesso dovrai specificare qualcosa del tipo:

python ./[file-to-execute].py

La parte #! è comunemente referenziata a shebang o a crunch bang .

    
risposta data user364819 04.11.2015 - 22:53
1

Se hai installato diverse versioni di Python, /usr/bin/env assicurerà che l'interprete utilizzato sia il primo sul $PATH dell'ambiente. L'alternativa sarebbe quella di hardcode qualcosa come #!/usr/bin/python ;

In Unix, un file eseguibile che deve essere interpretato può indicare quale interprete utilizzare avendo un #! all'inizio della prima riga, seguito dall'interprete (e dai flag eventualmente necessari).

Questa regola si applica solo al sistema basato su UNIX.

    
risposta data orvi 19.12.2015 - 14:34

Leggi altre domande sui tag