Pourquoi n'obtiens-je aucune erreur de syntaxe lorsque j'exécute mon script Python avec Perl?

85

Je viens d'écrire du code Python de test dans test.py, et je le lance comme suit:

perl test.py

Au bout d'un moment, j'ai réalisé mon erreur. Je dis "après un certain temps", car le code Python est en fait correctement exécuté, comme dans l'interpréteur Python!

Pourquoi mon Perl interprète-t-il mon Python? test.pyressemble à ça:

#!/usr/bin/python

...Python code here...

Fait intéressant, si je fais le contraire (c'est-à-dire appeler python something.pl), j'obtiens beaucoup d'erreurs de syntaxe.

Dacav
la source
6
Je suppose que c'est à cause du #!début du fichier. En effet si j'enlève le she-bang, j'obtiens le comportement attendu. N'est-ce pas une mauvaise idée du point de vue de la sécurité, de toute façon?
Dacav
7
Non. Le point du chemin shebang est de spécifier un interprète. Si vous ne faites pas confiance au code pour s'exécuter, vous ne devriez pas l'exécuter en premier lieu.
Sobrique
1
Non, pas vraiment. Votre script est un fichier texte. Ni plus ni moins. Il ne «fonctionnera» pas sans interprète.
Sobrique
4
"Pourquoi mon Perl interprète-t-il mon Python?" n'est pas «un problème qui ne peut plus être reproduit ou une simple erreur typographique». Voté pour rouvrir. Les votes positifs sur le Q et le A montrent que c'est une question d'intérêt populaire.
ikegami
1
@ikegami Indépendamment de sa popularité, il ne s'agit clairement pas "d'une simple erreur typographique ... résolue d'une manière peu susceptible d'aider les futurs lecteurs". Voté pour rouvrir.
ThisSuitIsBlackNot

Réponses:

114

De perlrun ,

Si la #!ligne ne contient ni le mot «perl» ni le mot «indir», le programme nommé d'après le #!est exécuté à la place de l'interpréteur Perl. C'est un peu bizarre, mais cela aide les gens sur des machines qui ne le font pas #!, car ils peuvent dire à un programme que leur SHELL est / usr / bin / perl , et Perl enverra alors le programme à l'interpréteur approprié pour eux.

Par exemple,

$ cat a
#!/bin/cat
meow

$ perl a
#!/bin/cat
meow
ikegami
la source
32
Sensationnel. Parlez de vos caractéristiques obscures. J'utilise Perl depuis plus de 20 ans et je n'avais aucune idée de ce qu'il faisait.
cjm
4
J'ai commencé à utiliser Perl v4 sous DOS, VMS et Solaris. Ce sont des fonctionnalités indépendantes du système d'exploitation / de pontage comme celle-ci qui ont tellement simplifié la vie multiplateforme.
tjd
1
@MarcvanLeeuwen Lorsque vous écrivez des programmes pour Linux, OSX, VAX / VMS, Windows, Solaris, OS / 2, et toute autre partie la plus ennuyeuse du portage d'un programme en langage de script est de le démarrer, comme beaucoup de ces systèmes, bien que généralement partager la fonctionnalité "taper une commande, la faire trouver et l'exécuter" en commun, faire presque tout le reste différemment. Cette fonctionnalité Perl fait de Perl un pont entre les fonctionnalités facile - vous pouvez écrire juste un shebang de style Unix et si Perl est présent, le code, que ce soit du code Perl ou non, fonctionnera toujours - c'est plus universel #! /usr/bin/env foo.
zxq9
1
@immibis Du fil de discussion Shebang line parsing mystery sur la liste de diffusion perl5-porters: " indirétait un programme conçu pour exécuter indirectement d'autres programmes. Je me souviens qu'il était censé être particulièrement utile dans les situations setuid où le système d'exploitation ne fournissait pas nativement vous aidez beaucoup, et / ou peut-être dans des situations où le noyau du système d'exploitation vous limitait à 32 lignes de commande de caractères. "
ThisSuitIsBlackNot
2
Cela renforce la réputation de Perl en tant qu'évier de cuisine des langages de programmation. Comme observation intéressante, je crois que l'implémentation originale de shebang était une fonctionnalité du shell, elle n'a été déplacée dans le noyau Unix que plus tard. Perl inclut de nombreux mécanismes shell (par exemple, des backticks pour remplacer la sortie de commande), ce n'est qu'un de plus.
Barmar le