Search code examples
linuxperlshebang

perl shebang: `Too late for "-Mstrict" `


I've got the following respectable perl script x.pl:

#!/usr/bin/env -S perl -Mstrict -wp
s/a/b/;

If I run it with either ./x.pl or perl x.pl, it bombs out with

Too late for "-Mstrict" option at ./x.pl line 1.

But... why? I thought "too late..." was only a problem with the likes of -CSDA or -T, because "the streams are already open". Besides, doesn't the shebang line actually simply invoke perl with the specified switches?


Solution

  • This is an intentional warning, not something failing to load. They want to put you off from ever trying to load modules on the shebang line even though it (sometimes) actually works. This is because Perl has no guarantees how the OS parsed and executed the script's shebang line. So it's just forbidden. Read perlrun for more information. Perl actually reparses the shebang line after startup to check for options that weren't passed correctly at execution time.

    $ cat script.pl
    
        #!/usr/bin/perl -w -Mthing
        print "Hello world\n";
    
    $ cat thing.pm
    
        package thing;
        $|=1;
        print "thing was loaded\n";
        sub import { print "thing import was imported\n"; }
    
    $ ./script.pl
    thing was loaded
    thing import was imported
    Too late for "-Mthing" option at ./script.pl line 1.
    
    $ perl ./script.pl
    Too late for "-Mthing" option at ./script.pl line 1.
    
    $ perl -x ./script.pl
    thing was loaded
    thing import was imported
    Hello world
    
    
    

    I agree it's a little archaic nowadays but it's a way to seperate OS execution from your program.