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

Viewed 143

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?

2 Answers

-M and -m switches are not intended for use inside a Perl script.

#!/usr/bin/perl -Mstrict
# shebang.pl
print 42;

$ perl -Mdiagnostics shebang.pl

Too late for "-Mstrict" option at - line 1 (#1) (X) The #! line (or local equivalent) in a Perl script contains the -M, -m or -C option.

In the case of -M and -m, this is an error because those options are not intended for use inside scripts. Use the use pragma instead.

The -C option only works if it is specified on the command line as well (with the same sequence of letters or numbers following). Either specify this option on the command line, or, if your system supports it, make your script executable and run it directly instead of passing it to perl.

Uncaught exception from user code: Too late for "-Mstrict" option at - line 1.

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.

Related