Pourquoi Python sous Linux exige-t-il la ligne #! / usr / bin / python?

50

Très simple question: sous Linux, pourquoi Python a-t-il besoin de la ligne

#!/usr/bin/python

au début d'un fichier python, puisque Windows ne le fait pas?

Que fait-il? Parce que la description "Liens vers Python" est un peu vague ...

    
posée DevRobot 04.11.2015 - 22:48
la source

7 réponses

56

Python n’a pas de condition particulière sur Linux. C'est le programme de chargement sous Unix / Linux qui utilise la ligne "shebang", comme on l’appelle. C'est en fait une fonctionnalité plutôt qu'une limitation, mais nous y arriverons dans un instant. La page Wiki sur "shebang" a plus de détails, mais j'essaierai aussi de donner un aperçu en comparaison avec Windows ici.

Tout d’abord, examinons la situation sous Windows:

  • Lorsque vous essayez d'ouvrir ou d'exécuter un fichier, Windows examine d'abord l'extension de ce fichier. C'est la partie last du nom de fichier commençant par . . Dans le cas des fichiers Python, il s'agit généralement de .py .
  • Windows recherche l’action à entreprendre en fonction de l’extension du fichier.
    • Cette information est enregistrée dans le registre Windows; Lorsque Python est installé, il indique généralement à Windows que les fichiers .py doivent être ouverts à l'aide de l'application Python (l'interpréteur Python) nouvellement installée.
    • Plusieurs types de fichiers ont des comportements intégrés; Par exemple, les fichiers exécutables (tels que l'interpréteur Python lui-même) doivent se terminer par .exe et les fichiers .bat sont exécutés en tant que scripts par lots Windows.
    • L'action prise pour un type de fichier particulier est personnalisable . Vous pouvez, par exemple, indiquer à Windows qu'au lieu d'exécuter les fichiers .py en utilisant python.exe , il devrait les ouvrir avec un autre programme, tel que l'éditeur de texte notepad.exe .
      • Dans ce cas, pour exécuter un script Python, vous devez manuellement appeler python <scriptname>.py (ou écrire un fichier .bat pour cela). vous).

Que se passe-t-il si une ligne de shebang ( #!/usr/bin/python ou #!/usr/bin/env python ) se trouve en haut du script Python? Eh bien, puisque # est une ligne de commentaire dans Python, l'interpréteur Python l'ignore. C'est l'une des raisons pour lesquelles la plupart des langages de script utilisés dans le monde Unix / Linux utilisent # pour démarrer les lignes de commentaires.

Il est donc un peu trompeur de dire que Windows "n'a pas besoin" de la ligne #! ; Windows ne voit pas la ligne #! et s'appuie en fait sur l'extension de fichier pour lui dire quoi faire. Cela a quelques inconvénients:

  • Vous devez nommer les scripts Python avec .py à la fin afin de les reconnaître automatiquement comme tels.
  • Il n’ya pas de moyen facile de distinguer les scripts Python2 des scripts Python3.
  • Comme indiqué précédemment, si vous modifiez le comportement de lancement par défaut pour le type de fichier .py , Windows n'exécutera plus automatiquement ces scripts avec Python. Notez que cela pourrait être fait involontairement.

Maintenant, regardons comment Unix / Linux lance des scripts:

La première chose à noter est que, contrairement à Windows, Unix / Linux ne cherche pas à "ouvrir" les scripts Python en utilisant un programme particulier, au moins conceptuellement; le système d'exploitation sait que le script est quelque chose qui peut être exécuté à cause de quelque chose appelé le "bit d'exécution" (ce qui sort du cadre de cette réponse). Donc, si vous tapez accidentellement #!/usr/bin/pthon au lieu de #!/usr/bin/python , vous obtiendrez un message d'erreur incluant ce texte:

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

Le mot "interprète" nous donne un indice sur le rôle de la ligne shebang (bien que techniquement le programme spécifié puisse être autre chose qu'un interpréteur, tel que cat ou un éditeur de texte). Lorsque vous essayez d'exécuter un fichier, voici ce qui se passe:

  • Le chargeur de programme Unix / Linux examine les deux premiers octets de ce fichier; Si ces deux octets sont #! , le chargeur interprète le reste de la ligne shebang (à l'exception du shebang lui-même) comme une commande pour lancer un interpréteur avec lequel exécuter le contenu du fichier en tant que script.
  • Le chargeur de programme lance l’interpréteur spécifié, en lui fournissant le chemin du fichier original en tant qu’argument.

Cela présente quelques avantages:

  • Le scripteur a plus de contrôle sur l'interpréteur qui sera utilisé (ce qui résout le problème de Python2 / Python3) et peut parfois transmettre un argument supplémentaire à l'interpréteur (voir la page Wiki pour plus de détails).
  • Le nom de fichier du script est ignoré , vous pouvez donc nommer les scripts Python comme vous le souhaitez.

Notez enfin qu'Unix / Linux n'a pas besoin de la ligne shebang pour exécuter un script Python. Rappelez-vous que toute la ligne shebang permet réellement au chargeur de programme de sélectionner un interpréteur. Mais comme dans Windows, cela peut être fait manuellement:

python <myscript>
    
réponse donnée Kyle Strand 05.11.2015 - 23:25
la source
41

La ligne que vous avez indiquée est utilisée pour indiquer à l'ordinateur quel programme / interpréteur utiliser lors de l'exécution directe du fichier / script, ainsi que tous les arguments à transmettre à ce programme lors de l'exécution du script. Ce n'est cependant pas une exigence de Python , c'est une exigence du noyau / système linux si vous avez l'intention d'exécuter le script directement (et non de le transmettre à Python par la syntaxe ci-dessous). p>

Il n'est pas nécessaire si vous allez exécuter python script.py ou similaire. Il n'est nécessaire que si vous avez l'intention d'exécuter directement le script / fichier sans fournir l'interpréteur à utiliser (tel que python ).

Pour un script Bash, il aurait quelque chose comme ça:

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

Cela indiquerait au système que, lorsqu’elle s'exécute, elle devrait être exécutée via /bin/bash , qui est l’un des langages shells / shell-script du système.

Pour le code Python, cependant, ici, vous allez vouloir faire fonctionner le fichier exécutable via Python, vous lui dites donc quel interpréteur vous souhaitez avoir.

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

Ceci, comme pour Bash, indique que /usr/bin/python doit être utilisé (il s'agit probablement de Python 2 ou Python 3, selon les configurations de votre système).

De cette façon, vous pouvez exécuter directement ./filename.py ou ./executable ou ./scripttorun .

Sans cette ligne au début, et en supposant que le fichier / script soit exécutable, et en supposant que vous travaillez avec un script Python, vous devrez exécuter python filename.py ou similaire si vous n’avez pas le #!/usr/bin/python ligne. (Pour un script Bash, vous devez faire bash script.sh , ou similaire pour d'autres scripts / langages, tels que Perl, Ruby, etc.)

La mise en évidence de la syntaxe ci-dessus est spécifique à la langue dans chaque section, même si cela n'a pas vraiment d'importance.

    
réponse donnée Thomas Ward 04.11.2015 - 22:53
la source
16

La ligne:

#!/usr/bin/python

s'appelle le "shebang" et indique le chemin d'accès à l'interpréteur binaire qui sera utilisé pour interpréter le reste des commandes du fichier. C'est généralement la première ligne d'un script.

La ligne #!/usr/bin/python indique donc que le contenu du fichier sera interprété par le% binaire python situé à /usr/bin/python .

Notez que la ligne shebang est analysée par le noyau, puis le script sera éventuellement appelé en argument:

python script_name

De même dans le cas de #!/bin/bash :

bash script_name
    
réponse donnée heemayl 04.11.2015 - 22:57
la source
7

Techniquement, cela ne l'exige pas. Il nécessite un chemin vers l'environnement d'exécution de votre script. Vos futurs scripts auraient intérêt à inclure / usr / bin / env alors, spécifiez python. Cela signifie que votre script s'exécute dans l'environnement python, peu importe où python est installé. Vous voulez le faire pour des raisons de compatibilité, vous ne pouvez pas être sûr que python sera installé dans usr / bin / python sur la prochaine personne avec laquelle vous partagez votre code, ou qu'ils auront des autorisations sur ces fichiers système.

Voici un questionnaire similaire sur le débordement de la pile .

À quoi ressemble votre script:

#!/usr/bin/env python

Je vois aussi quelques soucis sur la façon de spécifier python3. Voici comment faire:

#!/usr/bin/env python3
    
réponse donnée j0h 05.11.2015 - 17:50
la source
5

Sous Linux, Python peut ou non nécessiter la ligne #! (shebang). Cela dépend de la manière dont les codes Python sont gérés, soit en exécutant les codes en mode interactif Python, soit dans un script Python.

Le mode interactif Python permet à l'utilisateur de taper et d'exécuter directement les codes Python, ce qui ne nécessite pas la ligne shebang. Pour exécuter le mode interactif, ouvrez un terminal et tapez python pour Python 2.X ou python3 pour 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.
>>>

Le script Python permet à l'utilisateur d'écrire et de sauvegarder les codes Python dans un fichier texte brut, puis d'exécuter les codes ultérieurement. Cela peut ou non exiger la ligne de shebang. Cependant, il existe deux raisons connues pour lesquelles la ligne shebang est requise pour utiliser un script Python sous Linux.

  1. pour exécuter des codes Python dans un script exécutable, c’est-à-dire définir comment les codes doivent être exécutés et utiliser quel interpréteur;

  2. exécuter des codes Python en fonction de la version spécifique de Python, c’est-à-dire exécuter uniquement des codes compatibles avec Python 2.X ou Python 3.X uniquement

Entraînez-vous avec les scripts Python

Vous trouverez ci-dessous la liste et le contenu des fichiers que j'ai utilisés pour montrer les cas où la ligne #! (shebang) est requise ou non.

$  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 contient uniquement du code source.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py contient le code source et la ligne shebang.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py contient le même que hello2.py et est rendu exécutable.

  • hello3.py contient le même que hello2.py , sauf qu'il est adapté pour fonctionner avec Python 3 en renommant la première ligne en #!/usr/bin/env python3 .

  • hello3e.py contient le même que hello3.py et est rendu exécutable.

  • hello3m.py contient la même chose que hello3.py et est devenu exécutable, sauf enregistré avec l'option Write Unicode BOM dans l'éditeur de texte, par exemple Mousepad.

Au-delà de ce point, l’utilisateur aura deux méthodes pour exécuter les scripts Python. Les deux méthodes ont été démontrées comme ci-dessous.

Méthode 1: Exécuter avec le programme Python

Vous trouverez ci-dessous les commandes et les résultats lors de l’exécution du code source avec Python 2 et 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!

Les deux versions de Python ont pu exécuter le script avec succès. Par conséquent, la ligne shebang est non requise lors de l'exécution du script Python via la commande python ou python3 .

Méthode 2: Exécuter en tant que script Python

Vous trouverez ci-dessous les commandes et les résultats lors de l’exécution du code source avec la ligne shebang, qui ne sont adaptés ni à Python 2 ni à Python 3, y compris les cas non exécutables et exécutables.

$  ./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!

Les trois premiers scripts ont échoué car ces scripts ne sont pas exécutables, qu’ils aient ou non une ligne shebang (pour la preuve, voir Exemple supplémentaire ci-dessous). Les deux derniers scripts ont une ligne shebang et sont exécutables.

Apparemment, un script qui a été rendu exécutable est essentiellement inutile sans la ligne shebang. Par conséquent, la ligne shebang est requise et le script doit être exécutable lors de l'exécution des codes Python dans un script exécutable.

Quand le shebang ne fonctionne pas

Dans mon exemple préparé et testé, l'exécution de hello3m.py en tant que script exécutable a échoué et a renvoyé une erreur.

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

Il s’agit d’une limitation connue selon laquelle shebang ne fonctionne pas ou devient invalide. Lorsqu'un fichier est enregistré en tant que nomenclature Unicode (marque d'ordre d'octet), il ne pourra pas s'exécuter normalement en tant que script Python exécutable.

Exemple supplémentaire

Cet exemple supplémentaire sera traité comme preuve à l'appui uniquement. L'utilisateur doit éviter d'exécuter cet exemple, même si le résultat est sans danger.

J'ai créé un autre fichier appelé hello1e.py , qui contient la même chose que hello1.py et rendu exécutable. L'exécution de ce script a renvoyé une erreur de syntaxe.

$  ./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,))'

Lors de l’exécution de ce script, le curseur de la souris devient d’abord un signe plus et ne fait rien en apparence. L'erreur de syntaxe ne sera pas affichée tant que je n'ai pas cliqué sur la fenêtre du bureau ou du terminal. Ensuite, ce script crée un fichier sys dans le même répertoire que le script.

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

Le fichier sys a été identifié comme fichier PostScript, sans extension de fichier. Ce fichier peut être ouvert dans l'afficheur de documents, c'est-à-dire Evince, et le fichier contient en fait une capture d'écran de la fenêtre sur laquelle j'ai cliqué précédemment. Selon mon expérience, le fichier peut atteindre quelques mégaoctets.

Une fois encore, la ligne shebang est requise et le script doit être exécutable lors de l’exécution du script Python en tant que script exécutable. Sinon, le script se comportera mal comme décrit ci-dessus.

Notes supplémentaires

Le terme "exécutable" ou "doit être exécutable" fait référence à l'autorisation d'exécuter le script.Pour cela, exécutez la commande chmod +x FILENAME dans Terminal ou cochez l'option "Autoriser ce fichier à s'exécuter en tant que programme" ou un élément similaire dans la fenêtre Propriétés d'un gestionnaire de fichiers.

Bien que d’autres réponses existantes aient couvert presque tout, cette réponse a été différente en utilisant des exemples pratiques pour expliquer la question. La syntaxe du code a été écrite avec soin, de sorte que les exemples peuvent être exécutés avec Python 2 ou Python 3 tel quel.

Les codes Python ont été adaptés depuis Utilisation de Python sous Windows et Utilisation de Python sur les plates-formes Unix , avec un code supplémentaire d'une seule ligne de l'omniprésent "Hello, World!" programme.

Tous les codes et commandes ont été entièrement testés et fonctionnent dans le système Xubuntu 14.04, sur lequel Python 2.7 et Python 3.4 étaient installés par défaut.

    
réponse donnée clearkimura 14.12.2015 - 19:19
la source
4

Cela signifie que lorsque ce fichier est exécuté, votre ordinateur sait l'exécuter avec le programme /usr/bin/python , c'est-à-dire comment vous le différenciez d'une autre langue, comme bash où vous feriez #!/bin/bash . C'est pour que vous puissiez simplement lancer:

./[file-to-execute]

Et il saura avec quel fichier l'exécuter, plutôt que de devoir vous-même spécifier avec quelque chose comme:

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

La partie #! est généralement appelée shebang ou crunch bang .

    
réponse donnée user364819 04.11.2015 - 22:53
la source
1

Si plusieurs versions de Python sont installées, /usr/bin/env s'assurera que l'interpréteur utilisé est le premier de $PATH de votre environnement. L'alternative serait de coder en dur quelque chose comme #!/usr/bin/python ;

Dans Unix, un fichier exécutable destiné à être interprété peut indiquer quel interpréteur utiliser en ayant un #! au début de la première ligne, suivi de l'interpréteur (et des indicateurs dont il peut avoir besoin).

Cette règle s’applique uniquement au système UNIX.

    
réponse donnée orvi 19.12.2015 - 14:34
la source

Lire d'autres questions sur les étiquettes