web-dev-qa-db-fra.com

Pourquoi Python sous Linux requiert-il la ligne #! / Usr / bin / python?

Question assez simple: Sous Linux, pourquoi Python nécessite-t-il la ligne

#!/usr/bin/python

au début d'un fichier python, contrairement à Windows?

Qu'est-ce que ça fait? 'Car la description "Links to Python" est un peu vague ...

50
TellMeWhy

Python n’a pas cette exigence spéciale sur Linux. C'est le chargeur de programme sous Unix/Linux qui utilise la ligne "Shebang", comme on l'appelle. Il s’agit en fait d’une fonctionnalité plutôt que d’une limitation, mais nous y reviendrons dans un instant. La page Wiki sur "Shebang" contient plus de détails, mais je vais essayer de vous donner un aperçu ainsi qu'une comparaison avec Windows ici.

Regardons d'abord la situation sous Windows:

  • Lorsque vous essayez d'ouvrir ou d'exécuter un fichier, Windows examine d'abord l'extension de ce fichier. Ceci est la dernière partie du nom de fichier commençant par .. Dans le cas de fichiers Python, il s'agit généralement de .py.
  • Windows recherche l'action à entreprendre en fonction de l'extension de fichier.
    • Ces informations sont enregistrées dans le registre Windows. Lorsque Python est installé, il indique généralement à Windows que les fichiers .py doivent être ouverts à l'aide de la nouvelle application Python (c'est-à-dire le Python interprète).
    • Plusieurs types de fichiers ont des comportements intégrés; Par exemple, les fichiers exécutables (tels que l'interprète Python lui-même) doivent se terminer par .exe et les fichiers .bat sont exécutés sous forme de scripts batch Windows.
    • L'action entreprise pour un type de fichier particulier est personnalisable . Vous pouvez, par exemple, dire à Windows qu'au lieu d'exécuter les fichiers .py à l'aide de 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 appeler manuellement python <scriptname>.py (ou écrire un .bat fichier pour le faire pour vous).

Que se passe-t-il s'il existe une ligne Shebang (#!/usr/bin/python ou #!/usr/bin/env python) en haut du script Python? Eh bien, puisque # est une ligne de commentaire en Python, l’interprète 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 commencer les lignes de commentaire.

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

  • Vous devez nommer Python scripts avec .py à la fin pour qu'ils soient automatiquement reconnus comme tels.
  • Il n'y a 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.

Voyons maintenant comment Unix/Linux lance les scripts:

La première chose à noter est que, contrairement à Windows, Unix/Linux n'essaye pas "d'ouvrir" les scripts Python à l'aide d'un programme particulier, du 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" (qui est en dehors du champ de cette réponse). Ainsi, si vous tapez accidentellement #!/usr/bin/pthon au lieu de #!/usr/bin/python, vous obtiendrez un message d'erreur contenant le texte suivant:

/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'exclusion du Shebang lui-même) comme une commande permettant de lancer un interpréteur avec lequel exécuter le contenu du fichier sous forme de script. .
  • Le chargeur de programme lance l'interpréteur spécifié en lui fournissant le chemin du fichier d'origine en tant qu'argument.

Cela présente quelques avantages:

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

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

python <myscript>
58
Kyle Strand

La ligne que vous avez indiquée est utilisée pour indiquer à l'ordinateur le programme/interpréteur à utiliser lors de l'exécution directe du fichier/script, ainsi que tous les arguments devant être transmis à ce programme lors de l'exécution du script. Cependant, ce n’est pas une exigence de Python, c’est une exigence du noyau/du système Linux si vous souhaitez exécuter le script directement (et ne pas le transmettre à Python par le syntaxe ci-dessous).

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


Pour un script Bash, cela ressemblerait à ceci:

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

Cela indiquerait au système que, lorsqu’il est exécuté, il doit être exécuté via /bin/bash, qui est l’un des langages shells/shell-script du système.


Pour le code Python, cependant, ici, vous souhaiterez que le fichier exécutable s'exécute via Python, afin de lui indiquer quel interpréteur vous souhaitez exécuter.

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

Ceci, comme pour Bash, indique que /usr/bin/python devrait être utilisé (il est probable que Python 2 ou Python 3, selon vos configurations système individuelles).


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 vous ayez défini le fichier/script pour qu'il 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'aviez pas la ligne #!/usr/bin/python. (Pour un script Bash, vous devez utiliser 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 aucune importance.

41
Thomas Ward

La ligne:

#!/usr/bin/python

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

Ainsi, la ligne #!/usr/bin/python indique 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 appelé comme argument:

python script_name

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

bash script_name
16
heemayl

Techniquement, cela ne l'exige pas. Cela nécessite un chemin d'accès à l'environnement où votre script s'exécute. Il serait préférable que vos futurs scripts incluent/usr/bin/env, spécifiez python. Cela garantit que votre script s'exécute dans l'environnement python peu importe où python est installé. Vous voulez faire cela pour des raisons de compatibilité, vous ne pouvez pas être sûr que la prochaine personne avec laquelle vous partagerez votre code aura python installée dans usr/bin/python, ou qu'elle aura les autorisations nécessaires sur ces fichiers système.

Voici un Q & A similaire du débordement de pile .

Voici à quoi cela ressemble dans votre script:

#!/usr/bin/env python

Je vois aussi un problème concernant la spécification de python3. Voici comment faire:

#!/usr/bin/env python3
7
j0h

Sous Linux, Python peut nécessiter ou non la ligne #! (Shebang). Cela dépend de la façon dont les codes Python sont gérés, qu'ils soient exécutés en mode interactif Python ou dans un script Python.

Le mode interactif Python permet à l'utilisateur de taper et d'exécuter directement les codes Python, qui ne nécessitent pas la ligne Shebang. Pour exécuter le mode interactif, ouvrez un terminal et saisissez 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, puis de les exécuter ultérieurement. Cela peut nécessiter ou non la ligne Shebang. Cependant, il existe deux raisons connues pour lesquelles la ligne Shebang est requise pour utiliser le script Python sous Linux.

  1. exécuter les codes Python dans un script exécutable, c’est-à-dire définir le mode d’exécution des codes et l’utilisation de quel interpréteur;

  2. pour exécuter Python codes par rapport à une version spécifique de Python, c'est-à-dire des codes compatibles avec Python 2.X ou Python 3 .X seulement

Entraînez-vous avec Python scripts

Vous trouverez ci-dessous la liste et le contenu des fichiers, que j’ai utilisés pour montrer aux 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 le 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 a été rendu exécutable.

  • hello3.py contient la même chose 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 a été rendu exécutable.

  • hello3m.py contient le même que hello3.py et a été rendu exécutable, sauf qu'il a été enregistré avec l'option Write Unicode BOM dans l'éditeur de texte, c'est-à-dire Mousepad.

Au-delà de ce point, deux méthodes d’exécution des scripts Python seront présentées à l’utilisateur. Les deux méthodes ont été démontrées 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 pas requise pour 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 ils ne sont pas exécutables, qu'ils aient ou non la ligne Shebang (Pour la preuve à l'appui, 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 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

Ceci est un limitation connue que Shebang ne fonctionne pas ou devient invalide. Lorsqu'un fichier est enregistré en tant que BOM Unicode (Byte Order Mark), il ne pourra pas s'exécuter normalement en tant que script exécutable Python.

Exemple supplémentaire

Cet exemple supplémentaire ne doit être considéré que comme une preuve à l'appui. L'utilisateur doit éviter d'exécuter cet exemple, même si le résultat est inoffensif.

J'ai créé un autre fichier appelé hello1e.py, qui contient le même que hello1.py et est devenu 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 jusqu'à ce que je clique sur la fenêtre du bureau ou du terminal. Ensuite, ce script créera 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é en tant que fichier PostScript, sans extension de fichier. Ce fichier peut être ouvert dans la visionneuse de documents, c'est-à-dire Evince, et le fichier contenait en fait une capture d'écran de la fenêtre sur laquelle j'avais cliqué précédemment. D'après 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 de la manière décrite ci-dessus.

Notes complémentaires

Le terme "rendu exécutable" ou "doit être exécutable" fait référence à la permission d'exécuter le script. Ceci est fait en exécutant la commande chmod +x FILENAME dans Terminal ou en cochant l’option "Autoriser l’exécution de ce fichier en tant que programme" ou quelque chose de similaire dans la fenêtre Propriétés . , dans un gestionnaire de fichiers.

Tandis que d'autres réponses existantes couvraient presque tout, cette réponse a adopté une approche différente en utilisant des exemples pratiques pour expliquer le problème. La syntaxe du code a été écrite avec soin, de telle sorte que les exemples puissent être exécutés avec Python 2 ou Python 3, en l’état.

Les codes Python ont été adaptés de tilisation de Python sous Windows et tilisation de Python sur les plates-formes Unix , avec le code supplémentaire à une 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 sont installés par défaut.

5
clearkimura

Cela signifie que lorsque ce fichier est exécuté, votre ordinateur sait qu'il doit l'exécuter avec le programme /usr/bin/python, c'est ainsi que vous le différencierez d'une autre langue, telle que 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 spécifier vous-même quelque chose comme:

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

La partie #! est généralement référencée en tant que Shebang ou crunch bang.

4
user364819

Si vous avez plusieurs versions de Python installées, /usr/bin/env veillera à ce que l'interpréteur utilisé soit la première sur $PATH de votre environnement. L'alternative serait de coder en dur quelque chose comme #!/usr/bin/python;

Sous Unix, un fichier exécutable censé ê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 de tous les indicateurs dont il pourrait avoir besoin).

Cette règle ne s'applique qu'aux systèmes UNIX.

1
orvi

utile pour les systèmes d'exploitation comme Linux où Python 2.x est toujours la norme, mais la plupart des gens téléchargent également la version 3.x.

2.x serait exécuté par défaut. Donc, mon code 3.x, je préfixe avec #!/Usr/bin/env python3 afin que 3.x exécute le code. Je peux même spécifier jusqu'à la révision mineure (python 3.x.y.z) si j'ai choisi les versions bêta ou juste des versions légèrement plus anciennes.

0
user21784