Почему в первой строке Python-скрипта пишут "#!/usr/bin/env python"?
Я замечаю, что в начале файлов на Python часто можно увидеть такие строки:
#!/usr/bin/env python
или
#!/usr/bin/env python3
Мне кажется, что эти файлы выполняются одинаково, даже если этой строки нет. В чем смысл добавления такой строки в файл? Как она влияет на выполнение скрипта?
5 ответ(ов)
Если у вас установлено несколько версий Python, использование /usr/bin/env
гарантирует, что интерпретатор будет выбран в соответствии с первой версией в вашем $PATH
. Альтернативный вариант — жестко указать интерпретатор, например, #!/usr/bin/python
; это допустимо, но менее гибко.
В Unix исполняемый файл, который должен быть интерпретирован, может указать, какой интерпретатор использовать, добавив в начало первой строки #!
, за которым следует путь к интерпретатору (вместе с любыми необходимыми флагами).
Если вы говорите о других платформах, то, конечно, это правило не применимо (но такой "shebang" не повредит и будет полезен, если вы когда-либо скопируете этот скрипт на платформу с Unix-базой, такую как Linux, Mac и т.д.).
Расширяя немного другие ответы, вот небольшой пример того, как ваши командные скрипты могут столкнуться с проблемами из-за неосмотрительного использования shebang-строк с /usr/bin/env
:
$ /usr/local/bin/python -V
Python 2.6.4
$ /usr/bin/python -V
Python 2.5.1
$ cat my_script.py
#!/usr/bin/env python
import json
print "hello, json"
$ PATH=/usr/local/bin:/usr/bin
$ ./my_script.py
hello, json
$ PATH=/usr/bin:/usr/local/bin
$ ./my_script.py
Traceback (most recent call last):
File "./my_script.py", line 2, in <module>
import json
ImportError: No module named json
Модуль json отсутствует в Python 2.5.
Одним из способов защититься от такой проблемы является использование версионированных имен команд python, которые обычно устанавливаются с большинством дистрибутивов Python:
$ cat my_script.py
#!/usr/bin/env python2.6
import json
print "hello, json"
Если вам нужно просто различать Python 2.x и Python 3.x, то в последних версиях Python 3 также доступно имя python3
:
$ cat my_script.py
#!/usr/bin/env python3
import json
print("hello, json")
Возможно, ваш вопрос заключается в следующем:
Если вы хотите использовать команду: $python myscript.py
, то вам не нужно указывать эту строку (shebang) в начале вашего скрипта. Операционная система вызовет интерпретатор Python, и он выполнит ваш скрипт.
Однако, если вы планируете запускать его напрямую, используя: $./myscript.py
, то вам нужно указать эту строку, чтобы задать системе, какую программу использовать для его выполнения (и также сделать файл исполняемым с помощью команды chmod 755
).
Это соглашение в оболочке, которое указывает оболочке, какая программа может выполнить скрипт.
Строка:
#!/usr/bin/env python
разрешается в путь к двоичному файлу Python.
Это просто указывает, какой интерпретатор вы хотите использовать. Чтобы разобраться в этом, создайте файл через терминал, выполнив команду 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'
Это происходит потому, что Python 3 не поддерживает синтаксис вызова print без скобок.
Теперь измените первую строку вашего кода на:
#!/usr/bin/env python2
После этого скрипт сработает, напечатав test
в стандартный вывод, потому что Python 2 поддерживает оператор print. Таким образом, вы узнали, как переключаться между интерпретаторами скриптов.
Запуск команд оболочки и захват вывода
Сохранить график в файл изображения вместо его отображения
Преобразование списка словарей в DataFrame pandas
Как использовать десятичное значение шага в range()?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе