13

Почему в первой строке Python-скрипта пишут "#!/usr/bin/env python"?

10

Я замечаю, что в начале файлов на Python часто можно увидеть такие строки:

#!/usr/bin/env python

или

#!/usr/bin/env python3

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

5 ответ(ов)

13

Если у вас установлено несколько версий Python, использование /usr/bin/env гарантирует, что интерпретатор будет выбран в соответствии с первой версией в вашем $PATH. Альтернативный вариант — жестко указать интерпретатор, например, #!/usr/bin/python; это допустимо, но менее гибко.

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

Если вы говорите о других платформах, то, конечно, это правило не применимо (но такой "shebang" не повредит и будет полезен, если вы когда-либо скопируете этот скрипт на платформу с Unix-базой, такую как Linux, Mac и т.д.).

1

Расширяя немного другие ответы, вот небольшой пример того, как ваши командные скрипты могут столкнуться с проблемами из-за неосмотрительного использования 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")
0

Возможно, ваш вопрос заключается в следующем:

Если вы хотите использовать команду: $python myscript.py, то вам не нужно указывать эту строку (shebang) в начале вашего скрипта. Операционная система вызовет интерпретатор Python, и он выполнит ваш скрипт.

Однако, если вы планируете запускать его напрямую, используя: $./myscript.py, то вам нужно указать эту строку, чтобы задать системе, какую программу использовать для его выполнения (и также сделать файл исполняемым с помощью команды chmod 755).

0

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

Строка:

#!/usr/bin/env python

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

0

Это просто указывает, какой интерпретатор вы хотите использовать. Чтобы разобраться в этом, создайте файл через терминал, выполнив команду 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. Таким образом, вы узнали, как переключаться между интерпретаторами скриптов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь