Как: # use perl eval 'exe c perl -S $ 0 $ {1 + "$ @"}' устанавливает версию perl? - PullRequest
3 голосов
/ 09 мая 2020

Мне нужно отладить старый perl скрипт, который, по-видимому, устанавливает версию perl способом, который я не понимаю ...

: # use perl
    eval 'exec perl -S $0 ${1+"$@"}'
    if 0;

perl -h говорит, что -S означает «искать программный файл с помощью переменной окружения PATH». $0 - текущая программа. И я читал, что $@ означает «Сообщение об ошибке синтаксиса Perl из последней команды eval». Но почему они добавляют к этому единицу? И как все это сочетается? Что он делает?

Часть того, что мне нужно отладить, связано с тем, что он выбирает старую версию perl, которая мне не нужна. Для всего остального мы используем #!/usr/bin/env perl, который, как я подозреваю, может делать то же самое. Я также подозреваю, что мое решение может ie исправлять $PATH (или предотвращать обман кода, который обманывает его). Но я хотел бы go здесь, чтобы лучше понять, как сейчас выбирается версия.

Спасибо за любую помощь!

1 Ответ

5 голосов
/ 09 мая 2020

Это предназначено для запуска любой версии perl, первой на вашем пути, обрабатывая сценарий сначала как сценарий оболочки, который затем выполняет perl. В этом контексте ${1+"$@"} - это аргументы (если есть), переданные скрипту.

Из руководства bash:

${parameter:+word}

Если параметр равен нулю или не установлен, ничего не подставляется, в противном случае подставляется расширение слова.

и

Пропуск двоеточия приводит к проверке только параметра, который не установлено

Аналогичный пример есть в perlrun :

Этот пример работает на многих платформах, у которых есть оболочка, совместимая с оболочкой Bourne:

#!/usr/bin/perl
eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
  if $running_under_some_shell;

Система игнорирует первую строку и передает программу на /bin/sh, который продолжает попытки выполнить программу Perl как сценарий оболочки. Оболочка выполняет вторую строку как обычную команду оболочки и, таким образом, запускает интерпретатор Perl. В некоторых системах $0 не всегда содержит полный путь, поэтому -S сообщает Perl о необходимости поиска программы при необходимости. После того, как Perl находит программу, она анализирует строки и игнорирует их, потому что переменная $running_under_some_shell никогда не является истинной. Если программа будет интерпретироваться как csh, вам нужно будет заменить ${1+"$@"} на $*, даже если он не понимает встроенные пробелы (и тому подобное) в списке аргументов. Для запуска sh вместо csh в некоторых системах может потребоваться заменить символ #! строка со строкой, содержащей только двоеточие, которое будет вежливо проигнорировано командой Perl.

Использование /usr/bin/env - это еще один способ сделать то же самое, да.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...