87

I just wrote some testing python code into test.py, and I'm launching it as follows:

perl test.py

After a while I realized my mistake. I say "after a while", because the Python code gets actually correctly executed, as if in Python interpreter!

Why is my Perl interpreting my Python? test.py looks like this:

#!/usr/bin/python

...Python code here...

Interestingly, if I do the opposite (i.e. call python something.pl) I get a good deal of syntax errors.

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Dacav
  • 13,590
  • 11
  • 60
  • 87
  • 6
    I'm guessing it's because of the `#!` in the beginning of the file. Indeed if I remove the she-bang, I'm getting the expected behavior. Isn't that a bad idea from the security perspective, anyway? – Dacav Apr 10 '15 at 14:20
  • 8
    No. The point of the shebang path it to specify an interpreter. If you don't trust the code to run, then you shouldn't be running it in the first place. – Sobrique Apr 10 '15 at 14:21
  • @Sobrique, fair point... still there's something inherently odd here. – Dacav Apr 10 '15 at 14:23
  • 1
    No, not really. Your script is a text file. No more, no less. It won't 'run' without an interpreter. – Sobrique Apr 10 '15 at 14:23
  • All depends on the content of your file. The interpreter for each language will try to execute the code in the corresponding language. – styts Apr 10 '15 at 14:25
  • 4
    "Why is my Perl interpreting my Python?" is not "a problem that can no longer be reproduced or a simple typographical error." Voted to reopen. The upvotes on the Q and the A show this is a question of popular interest. – ikegami Apr 10 '15 at 20:28
  • 2
    @ikegami Regardless of popularity, this is clearly not "a simple typographical error...resolved in a manner unlikely to help future readers." Voted to reopen. – ThisSuitIsBlackNot Apr 10 '15 at 20:37
  • (I'm a bit astonished on how much points I'm getting for this question... I tought it was a dumb question to ask, and I should have read perlrun...) – Dacav Apr 16 '15 at 12:33
  • Perl.com explains it in detail in [Bang Bang](https://www.perl.com/article/bang-bang/). – brian d foy Jan 06 '21 at 18:46

1 Answers1

114

From perlrun,

If the #! line does not contain the word "perl" nor the word "indir" the program named after the #! is executed instead of the Perl interpreter. This is slightly bizarre, but it helps people on machines that don't do #! , because they can tell a program that their SHELL is /usr/bin/perl, and Perl will then dispatch the program to the correct interpreter for them.

For example,

$ cat a
#!/bin/cat
meow

$ perl a
#!/bin/cat
meow
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 33
    Wow. Talk about your obscure features. I've been using Perl for more than 20 years, and I had no idea it did that. – cjm Apr 10 '15 at 15:17
  • 4
    I started using Perl v4 on DOS, VMS & Solaris. It's OS agnostic/bridging features like this that made cross platform life so much easier. – tjd Apr 10 '15 at 16:45
  • I find the documentation rather bizarre in itself. Why the hell would "on machines that don't do `#!`" there be scripts that start with `#!` in the first place? I don't think having `/usr/bin/perl` (and I would doubt that on mentioned machines it would actually be that path) as you `SHELL` would be any fun. – Marc van Leeuwen Apr 11 '15 at 05:07
  • 1
    @MarcvanLeeuwen When you write programs for Linux, OSX, VAX/VMS, Windows, Solaris, OS/2, and whatever else the most annoying part of porting a script-language program is getting it started, as many of these systems, though usually sharing the "type a command, have it found & executed" feature in common, do nearly everything else differently. This Perl feature makes Perl an easy gap-bridge in functionality -- you can write *just* a Unix-style shebang and if Perl is present the code, whether Perl code or not, will *always* work -- its like a more universal `#! /usr/bin/env foo`. – zxq9 Apr 11 '15 at 08:44
  • 1
    @immibis From the thread [Shebang line parsing mystery](https://groups.google.com/forum/m/#!topic/perl.perl5.porters/UlKtqq6q0JA) on the perl5-porters mailing list: "`indir` was a program designed to indirectly execute other programs. My recollection is that it was supposed to be particularly useful in setuid situations where the OS didn't natively provide you much help, and/or perhaps in situations where the OS kernel limited you to 32 character command lines." – ThisSuitIsBlackNot Apr 12 '15 at 04:25
  • GG Perl knows you didn't mean to invoke perl and sends the work to the right executable anyway. What a swell guy! – Maurice Reeves Apr 14 '15 at 21:47
  • 2
    This just cements Perl's reputation as the kitchen sink of programming languages. As an interesting observation, I believe the original implementation of shebang was as a shell feature, it only moved into the Unix kernel later. Perl includes many shell mechanism (e.g. backticks for substituting command output), this is just one more. – Barmar Apr 15 '15 at 19:56
  • 2
    `ruby` does the same >. – Vadim Pushtaev Apr 17 '15 at 07:50