В чем преимущество "#! / Usr / bin / env python" в shebang по сравнению с простым вызовом интерпретатора "#! Python"? - PullRequest
0 голосов
/ 11 октября 2019

Я понимаю разницу между запуском скрипта Python, например:

#!/usr/bin/env python

или

#!/usr/bin/python

Из того, что я понял, просто выполняется python, как мы это делаем в нашей оболочке, поэтомуэто выглядит в $PATH. Второй путь не является фиксированным путем, поэтому неудобно, что в другой системе интерпретатор python может находиться в другом пути.

Мой вопрос: зачем нам нужен env? Почему мы можем просто сделать:

#!python

Это прекрасно работает на моем компьютере? Есть ли причина предпочитать звонить env?

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

давайте представим, что ваш файл python называется tst.py и имеет следующее содержимое

#!python
import sys
print(sys.executable, sys.version)

, тогда вы всегда можете набрать

python tst.py

Первая строка совершенно неактуальна идаже не смотрел.

Однако, если вы выполните следующее (например, в Linux)

chmod +x tst.py
./tst.py

Затем просматривается первая строка, чтобы определить, какой интерпретатор будет использоваться (bash, perl,python, что-то еще?) и здесь, по крайней мере, для моей ОС (ubuntu) и моей оболочки (bash) требуется абсолютный путь для имени исполняемого файла (например, /bin/bash, /bin/python, /usr/bin/env)

Если я вызываю ./tst.py на моем компьютере с Ubuntu, я получаю

bash: ./tst.py: python: bad interpreter: No such file or directory

Особый случай Windows при вводе tst.py или щелчке скрипта на python. Если вы работаете в Windows, строка просматривается, но даже если она неверна, будет использован интерпретатор Python по умолчанию. В Windows эта строка может быть использована для явного выбора, например, python2 или python3. Windows использует ассоциации типов файлов, чтобы определить, какой исполняемый файл для вызова какого суффикса. для файлов .py (установлен python 3.x) обычно это py.exe, который является исполняемым файлом, расположенным в системном пути, который просто вызывает интерпретатор python. в зависимости от установленных версий, строки shebang и переменных среды, которые могут указывать на virtualenv

Приложение: Первая строка интерпретируется оболочкой или в случае Windows py.exe.

ItКажется, bash требует абсолютных путей для команды, тогда как zsh также принимает относительные пути.

Так что только для zsh

#!python

работает отлично, тогда как bash требует абсолютных путей и, таким образом, трюк с envкоманда

#!/usr/bin/env python

Для сценариев, которые должны выполняться cronjob, лучше жестко закодировать путь исполняемого файла python, поскольку PATH довольно минималистичен для cronjobs, поэтому лучше всего иметь что-то вроде

#!/usr/bin/python3.5

или

#!/home/username/myvirtualenv/bin/python
1 голос
/ 11 октября 2019

Каждый скрипт Python написан с учетом конкретной версии Python. Если значение shebang равно #!/usr/bin/env python, это означает, что используемая версия находится под контролем отдельного вызывающего абонента , чья PATH может не предоставить правильную версию.

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

Решение состоит в том, чтобы указать правильное местоположение в ваша система, когда вы устанавливаете модуль или скрипт. Установщик Python (pip и т. Д.) В это время переписывает любой шебанг, содержащий слово python (#!python - минимальный такой шебанг), в путь, указанный установщиком.

Теперь, когда вы запустите сценарий, он будет указывать на правильный путь, который вы уже указали, не подвергаясь поиску PATH во время выполнения, который может выбрать неправильную версию.

Обратите внимание, что #!pythonне предназначен для использования как есть, хотя по разным причинам может работать для вас. Это средство для обеспечения того, чтобы скрипт получал фиксированный, абсолютный путь к правильному интерпретатору. #!/usr/bin/python равно и подлежит замене во время установки, поэтому может использоваться в качестве используемого по умолчанию.

...