Как работает этот Perl Шебанг? (Для тех, кто не из Perl) - PullRequest
1 голос
/ 26 февраля 2020

Может ли кто-нибудь объяснить, как работает этот шебанг?

#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python3/r,$_)

Я видел, как он был опубликован здесь дважды, но не из Perl, мне кажется, что он волшебник c , Я спрашиваю, как я хотел бы настроить каталог для python среды относительно сценария.

то есть #!../env/bin/python3 до (я только здесь догадываюсь) #!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/env/bin/python3/r,$_)

Редактировать : Я пытаюсь выполнить простую программу "Hello world".

#!/usr/bin/perl -e'$_=$ARGV[0];exec(s{\w+$}{exploit-env/bin/python3}r,$_)'

###############################

def main():
    print('Hello world')

###############################

if __name__ == '__main__':
    main()

1 Ответ

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

Обработка Shebang не согласована во всех системах [1] , но ваша система, очевидно, выполняет то, что должна выполнить следующая команда оболочки (при условии, что файл, содержащий shebang * /path/to/script):

/usr/bin/perl -e'$_=$ARGV[0];exec(s/\w+$/python3/r,$_)' /path/to/script

(Путь к сценарию может не быть абсолютным путем - он может быть относительно текущего каталога - но здесь это не имеет значения.)

Сценарий создает /path/to/python3 из /path/to/script (заменяя завершающие символы «слова», которые включают буквы, цифры и подчеркивание, но не /), затем вычисляет

exec('/path/to/python3', '/path/to/script')

. Заменяет программу, выполняемую в текущем процессе, на Python интерпретатор, передавая путь к сценарию в качестве аргумента.


Если я правильно читаю между строк, вы хотите запустить /path/to/../env/bin/python3 вместо /path/to/python3. Для этого используйте одно из следующих значений:

#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/..\/env\/bin\/python3/r,$_)

или

#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,$_)

/ необходимо экранировать с помощью \, когда / используется в качестве разделитель (первое решение), но мы можем изменить разделитель для получения более читабельного результата (второе решение).


Тот шебанг, который вы представили, вызывает поглощение аргументов. Замените $_ на @ARGV, чтобы передать их.

#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,@ARGV)

  1. По крайней мере, исторически, некоторые системы рассматривают всю последовательность, которая следует за #!, как путь (т.е. нет аргументы позволяют), а некоторые имеют очень строгие ограничения на длину пути.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...