Почему люди пишут #! / Usr / bin / env pybang в первой строке скрипта Python? - PullRequest
936 голосов
/ 12 марта 2010

Мне кажется, что файлы без этой строки работают одинаково.

Ответы [ 19 ]

11 голосов
/ 12 марта 2010

Это соглашение оболочки, которое сообщает оболочке, какая программа может выполнить сценарий.

#!/usr/bin/env python

разрешает путь к двоичному файлу Python.

9 голосов
/ 21 декабря 2012

Вы можете попробовать эту проблему, используя virtualenv

Вот test.py

#! /usr/bin/env python
import sys
print(sys.version)

Создание виртуальных сред

virtualenv test2.6 -p /usr/bin/python2.6
virtualenv test2.7 -p /usr/bin/python2.7

активируйте каждую среду, затем проверьте различия

echo $PATH
./test.py
8 голосов
/ 12 марта 2010

Мне кажется, что файлы без этой строки работают одинаково.

Если это так, то, возможно, вы используете программу Python в Windows? Windows не использует эту строку - вместо этого она использует расширение имени файла для запуска программы, связанной с расширением файла.

Однако в 2011 году был разработан "Python launcher" , который (в некоторой степени) имитирует это поведение Linux для Windows. Это ограничивается только выбором, какой интерпретатор Python запускается - например, выбрать между Python 2 и Python 3 в системе, где установлены оба. Модуль запуска при необходимости устанавливается как py.exe при установке Python и может быть связан с файлами .py, так что модуль запуска проверяет эту строку и, в свою очередь, запускает указанную версию интерпретатора Python.

6 голосов
/ 29 ноября 2017

Это означает больше исторической информации, чем «реального» ответа.

Помните, что в те дни у вас было МНОЖЕСТВО Unix, таких как операционные системы, дизайнеры которых имели свое собственное представление о том, куда помещать вещи, а иногда не включали в себя Python, Perl, Bash или множество других GNU / Open Source вещи вообще .

Это справедливо даже для разных дистрибутивов Linux. В Linux - pre-FHS [1] - у вас может быть python в / usr / bin / или / usr / local / bin /. Или, возможно, он не был установлен, поэтому вы создали его и поместили в ~ / bin

Solaris был худшим из всех, над которыми я когда-либо работал, частично как переход с Berkeley Unix на System V. Вы можете оказаться с вещами в / usr /, / usr / local /, / usr / ucb, / opt / и т. Д. Это может сделать для некоторых действительно длинных путей. У меня есть воспоминания о том, как Sunfreeware.com устанавливал каждый пакет в свой собственный каталог, но я не могу вспомнить, содержит ли он символические ссылки в / usr / bin или нет.

Да, иногда / usr / bin находился на NFS-сервере [2].

Итак, утилита env была разработана, чтобы обойти это.

Тогда вы могли бы написать #!/bin/env interpreter, и, пока путь был верным, у вещей был разумный шанс на запуск. Конечно, разумный означал (для Python и Perl), что вы также установили соответствующие переменные среды. Для bash / ksh / zsh это просто сработало.

Это было важно, потому что люди передавали скрипты оболочки (такие как perl и python), и если вы жестко запрограммировали / usr / bin / python на вашей рабочей станции Red Hat Linux, то это будет плохо работать на SGI ... ну, нет, я думаю, что IRIX поставил python в нужное место. Но на станции Sparc он может вообще не работать.

Я скучаю по своей станции sparc. Но не много. Хорошо, теперь ты заставляешь меня троллить по E-Bay. Bastages.

[1] Стандарт иерархии файловой системы. https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

[2] Да, и иногда люди все еще делают подобные вещи. И нет, я не носил на поясе ни репы, ни лука.

6 голосов
/ 26 ноября 2016

Он просто указывает, какой интерпретатор вы хотите использовать. Чтобы понять это, создайте файл через терминал, выполнив touch test.py, затем введите в этот файл следующее:

#!/usr/bin/env python3
print "test"

и сделайте chmod +x test.py, чтобы сделать ваш скрипт исполняемым. После этого, когда вы делаете ./test.py, вы должны получить сообщение об ошибке:

  File "./test.py", line 2
    print "test"
               ^
SyntaxError: Missing parentheses in call to 'print'

потому что python3 не поддерживает оператор печати. ​​

Теперь перейдите и измените первую строку вашего кода на:

#!/usr/bin/env python2

и это будет работать, печатая test в стандартный вывод, потому что python2 поддерживает оператор печати. Итак, теперь вы узнали, как переключаться между интерпретаторами сценариев.

5 голосов
/ 06 апреля 2016

Если вы запускаете ваш скрипт в виртуальной среде, скажем venv, то выполнение which python при работе на venv покажет путь к интерпретатору Python:

~/Envs/venv/bin/python

Обратите внимание, что имя виртуальной среды встраивается в путь к интерпретатору Python.Поэтому жесткое кодирование этого пути в вашем скрипте вызовет две проблемы:

  • Если вы загрузите скрипт в репозиторий, вы заставите других пользователей иметь такое же имя виртуальной среды ,Это если они сначала идентифицируют проблему.
  • Вы не сможете запустить скрипт в нескольких виртуальных средах , даже если у вас были все необходимые пакеты в других виртуальных средах.

Поэтому, чтобы добавить к ответу Джонатана , идеальный шебанг составляет #!/usr/bin/env python, причем не только для переносимости между операционными системами, но и для переносимости через виртуальные среды.!

3 голосов
/ 18 мая 2016

Учитывая проблемы переносимости между python2 и python3, вы всегда должны указывать любую версию, если ваша программа не совместима с обеими.

Некоторые дистрибутивы поставляются python с символической ссылкой python3 дляв то время как сейчас - не полагайтесь на python, являющееся python2.

Это подчеркивается PEP 394 :

Для того, чтобы терпеть различия между платформамивесь новый код, который должен вызывать интерпретатор Python, не должен указывать python, а должен указывать либо python2, либо python3 (или более конкретные версии python2.x и python3.x; см. Примечания по миграции ).Это различие должно быть сделано в шебангах, при вызове из сценария оболочки, при вызове через вызов system () или при вызове в любом другом контексте.

2 голосов
/ 13 июня 2016

Сообщает интерпретатору, с какой версией python запускать программу, если у вас несколько версий python.

0 голосов
/ 17 января 2015

это говорит сценарию, где находится каталог python!

#! /usr/bin/env python
...