perl shebang: `Слишком поздно для -Mstrict`

У меня есть следующий респектабельный perl-скрипт x.pl:

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

Если я запускаю его с ./x.pl или perl x.pl, он вылетает с

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

Но почему? Я подумал слишком поздно... была проблема только с подобными -CSDA или -T, потому что потоки уже открыты. Кроме того, разве строка shebang на самом деле не просто вызывает Perl с указанными переключателями?


person usretc    schedule 17.11.2020    source источник
comment
Я предполагаю, что это связано с буквальной вставкой use strict; в поток. Просто используйте use strict;!   -  person ikegami    schedule 18.11.2020


Ответы (2)


Это преднамеренное предупреждение, а не ошибка загрузки. Они хотят, чтобы вы никогда не пытались загрузить модули в строку shebang, даже если это (иногда) действительно работает. Это связано с тем, что у Perl нет никаких гарантий того, как ОС анализирует и выполняет строку shebang скрипта. Так что это просто запрещено. Прочтите perlrun для получения дополнительной информации. Perl фактически повторно анализирует строку shebang после запуска, чтобы проверить параметры, которые не были переданы правильно во время выполнения.

$ 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


Я согласен, что в наши дни это немного архаично, но это способ отделить выполнение ОС от вашей программы.

person lordadmira    schedule 20.11.2020

Переключатели -M и -m не предназначены для использования внутри сценария Perl.

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

$ perl -Mdiagnostics shebang.pl

Слишком поздно для опции -Mstrict в строке 1 (#1) (X) #! строка (или локальный эквивалент) в скрипте Perl содержит параметр -M, -m или -C.

В случае -M и -m это ошибка, потому что эти опции не предназначены для использования внутри скриптов. Вместо этого используйте прагму use.

Параметр -C работает только в том случае, если он также указан в командной строке (с такой же последовательностью букв или цифр). Либо укажите эту опцию в командной строке, либо, если ваша система ее поддерживает, сделайте свой скрипт исполняемым и запустите его напрямую, а не передавайте в perl.

Неперехваченное исключение из пользовательского кода: слишком поздно для параметра -Mstrict в строке 1.

person mob    schedule 17.11.2020
comment
Я думаю, что ОП понимает, что -M не следует использовать там, и они хотят знать, почему. - person ikegami; 18.11.2020