Что значит "#! - * - perl - * -"? - PullRequest
2 голосов
/ 05 февраля 2020

В документах perl можно прочитать:

Синтаксический анализ #! Переключатели запускаются везде, где в строке указано «perl». Последовательности "- *" и "-" специально игнорируются, так что вы можете, если бы вы были так склонны, сказать

#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
    if 0; to let Perl see the -p switch.

, чтобы позволить Perl увидеть ключ -p.

Я запутался в комментарии. Строка "- - perl - -" находится внутри комментария, и shebang уже проанализирован. Если я напишу:

!/bin/sh
#! -*-python-*-
print 1

Это не сработает. Кроме того, эти последовательности всегда игнорируются? Означает ли это, что это что-то похожее на '/ bin / sh - perl'? Это терпит неудачу на терминале.

Тогда это также упоминает ключ "-p". Но в коде нет переключателя p.

Ответы [ 2 ]

3 голосов
/ 05 февраля 2020

Ваша цитата скопирована не полностью. Текст на самом деле говорит:

Синтаксический анализ ключей #! начинается везде, где в строке упоминается "perl". Последовательности -* и - специально игнорируются, поэтому вы могли бы, если бы вы были так склонны, сказать

#!/bin/sh --
#! -*- perl -*- -p
eval 'exec perl $0 -S ${1+"$@"}'
    if 0;

, чтобы позволить Perl увидеть переключатель -p.

Здесь есть три вещи:

  • Шебанг #!/bin/sh заставляет скрипт запускаться sh. eval 'exec ...' - это хак, чтобы заставить sh на exec perl, если это произойдет.
  • Спецификатор -*- perl -*- является строкой режима Emacs . Но это также по совпадению вызывает следующее поведение.
  • Второй #! вместе с текстом perl из предыдущего элемента - это то, что запускает описанный вариант разбора. Согласно правилам синтаксического анализа, строка режима игнорируется, и -p в конце этой строки выбирается как фактическая опция для Perl.

Предыдущие параграфы в документации возможно, для контекста также следует указывать:

Начиная с Perl 5, строка #! всегда проверяется на наличие переключателей при ее разборе. Таким образом, если вы находитесь на машине, которая допускает только один аргумент со строкой #! или, что еще хуже, даже не распознает строку #!, вы все равно можете получить согласованное поведение переключателя независимо от того, как был вызван Perl , даже если -x использовалось для поиска начала сценария.

Поскольку многие операционные системы молча отключают интерпретацию ядра строки #! после 32 символов, некоторые переключатели могут быть переданы команде линия, а некоторые нет; Вы могли бы даже получить - без его письма, если вы не будете осторожны. Вы, вероятно, хотите убедиться, что все ваши переключатели находятся до или после этой 32-символьной границы. Большинство переключателей фактически не заботятся о том, обрабатываются ли они избыточно, но получение - вместо полного переключателя может привести к тому, что Perl попытается выполнить стандартный ввод вместо вашего сценария. А частичный переключатель -I может также привести к нечетным результатам.

... И позже:

Если строка #! не содержит слова " perl ", программа, названная в честь #!, выполняется вместо интерпретатора Perl. Это немного странно, но это помогает людям на машинах, которые не делают #!, потому что они могут сказать программе, что их SHELL равен /usr/bin/perl, и Perl затем отправит программу нужному интерпретатору для их.

2 голосов
/ 05 февраля 2020

Это ошибка в документации. Исходная строка в сценарии была

# -*- perl -*- -p

См. этот запрос на извлечение .

...