Почему для Python в Linux требуется строка #! / usr / bin / python?

48

Довольно простой вопрос: в Linux, почему Python требует строку

#!/usr/bin/python

в начале файла python, так как Windows не работает?

Что он делает? потому что описание «Ссылки на Python» немного расплывчато ...

    
задан DevRobot 04.11.2015 в 22:48
источник

7 ответов

53

Python не имеет такого специального требования к Linux. Это программный загрузчик в Unix / Linux, который использует строку «shebang», как ее называют. На самом деле это скорее функция, а не ограничение, но мы доберемся до этого момента. Страница Wiki на странице «shebang» содержит более подробную информацию, , но я попытаюсь также дать обзор как сравнение с Windows здесь.

Сначала давайте посмотрим на ситуацию в Windows:

  • При попытке открыть или запустить файл Windows сначала проверит расширение этого файла. Это last часть имени файла, начиная с . . В случае файлов Python это обычно .py .
  • Windows ищет, какие действия следует предпринять на основе расширения файла.
    • Эта информация записывается в реестр Windows; когда Python установлен, он обычно сообщает Windows, что файлы .py должны быть открыты с использованием недавно установленного приложения Python (т. е. интерпретатора Python).
    • Несколько типов файлов имеют встроенное поведение; например, исполняемые файлы (например, сам интерпретатор Python) должны заканчиваться на .exe , а файлы .bat исполняются как пакетные скрипты Windows.
    • Действие, предпринятое для определенного типа файла, настраивается . Например, вы можете сказать Windows, что вместо того, чтобы запускать .py файлов, используя python.exe , он должен открыть их с помощью какой-либо другой программы, такой как текстовый редактор notepad.exe .
      • В этом случае, чтобы запустить скрипт Python, вам нужно вручную вызвать python <scriptname>.py (или написать файл .bat , чтобы сделать это для вы).

Теперь, что произойдет, если в верхней части скрипта Python есть строка shebang ( #!/usr/bin/python или #!/usr/bin/env python )? Ну, так как # - это строка комментариев в Python, интерпретатор Python просто игнорирует ее. Это одна из причин, почему большинство языков сценариев, используемых в мире Unix / Linux, используют # для запуска строк комментариев.

Так что немного ввести в заблуждение, что Windows «не нуждается» в строке #! ; Windows не видит строку #! и фактически полагается на расширение файла, чтобы сообщить ему, что делать. Это имеет несколько недостатков:

  • Вы должны называть скрипты Python с .py в конце, чтобы автоматически распознать их как таковые.
  • Нет простого способа отличить скрипты Python2 от скриптов Python3.
  • Как уже отмечалось, если вы измените поведение запуска по умолчанию для файлового типа .py , Windows больше не будет автоматически запускать эти сценарии с помощью Python. Обратите внимание, что это может быть сделано непреднамеренно.

Теперь давайте посмотрим, как Unix / Linux запускает скрипты:

Первое, что нужно отметить, это то, что Unix / Linux, в отличие от Windows, не пытается «открывать» скрипты Python, используя определенную программу, по крайней мере концептуально; OS знает , что скрипт - это что-то, что может быть выполнено из-за чего-то, называемого «бит выполнения» (который выходит за рамки этого ответа). Итак, если вы случайно наберете #!/usr/bin/pthon вместо #!/usr/bin/python , вы получите сообщение об ошибке, которое включает этот текст:

/usr/bin/pthon: bad interpreter: No such file or directory.

Слово «интерпретатор» дает нам представление о роли линии shebang (хотя технически указанная программа может быть чем-то иным, чем интерпретатором, таким как cat или текстовым редактором). Когда вы пытаетесь выполнить файл, вот что происходит:

  • Загрузитель программы Unix / Linux просматривает первые два байта этого файла; если эти два байта составляют #! , тогда загрузчик интерпретирует оставшуюся часть строки shebang (за исключением самого shebang) в качестве команды запуска интерпретатора , с помощью которого можно запускать содержимое файла в виде скрипта.
  • Загрузчик программ запускает указанный интерпретатор, в качестве аргумента подает его путь исходного файла.

Это имеет несколько преимуществ:

  • У сценариста больше контроля над использованием интерпретатора (который решает проблему Python2 / Python3) и иногда может передавать дополнительный аргумент интерпретатору (подробности см. на странице Wiki).
  • Имя файла сценария игнорируется , поэтому вы можете называть скрипты Python как хотите.

Обратите внимание, наконец, что Unix / Linux выполняет не необходимость строки shebang для запуска скрипта Python. Напомним, что вся строка shebang на самом деле позволяет загрузчику программы выбирать интерпретатор. Но так же, как в Windows, это можно сделать вручную:

python <myscript>
    
ответ дан Kyle Strand 05.11.2015 в 23:25
источник
41

Указанная строка используется, чтобы сообщить компьютеру, какую программу / интерпретатор использовать при непосредственном запуске файла / скрипта, и любые аргументы, которые должны быть переданы этой программе при запуске скрипта. Это, однако, не требование Python , это требование ядра / системы linux, если вы намереваетесь напрямую запускать скрипт (а не передавать его на Python с помощью синтаксиса ниже).

Это не нужно, если вы собираетесь выполнить python script.py или подобное. Это необходимо только в том случае, если вы намереваетесь напрямую запускать скрипт / файл, не предоставляя также интерпретатору (например, python ).

Для сценария Bash у него будет что-то вроде этого:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

Это означало бы систему, что при ее запуске она должна быть запущена через /bin/bash , которая является одним из языков shell / shell-script в системе.

Для кода Python, здесь, вы захотите, чтобы исполняемый файл запускался через Python, поэтому вы рассказываете, какой интерпретатор вы намереваетесь запустить в нем.

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

Это, как и для Bash, указывает, что следует использовать /usr/bin/python (это, вероятно, Python 2 или Python 3, в зависимости от ваших индивидуальных конфигураций системы).

Таким образом, вы можете напрямую запускать ./filename.py или ./executable или ./scripttorun .

Без этой строки в начале и при условии, что вы установили исполняемый файл / сценарий, и предположив, что вы работаете с скриптом Python, вам нужно будет запустить python filename.py или подобное, если у вас не было #!/usr/bin/python . (Для сценария Bash вам нужно будет сделать bash script.sh или подобное для других скриптов / языков, таких как Perl, Ruby и т. Д.)

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

    
ответ дан Thomas Ward 04.11.2015 в 22:53
16

Строка:

#!/usr/bin/python

называется «shebang», и он указывает путь к двоичному интерпретатору, который будет использоваться для интерпретации остальных команд в файле. Обычно это первая строка скрипта.

Таким образом, строка #!/usr/bin/python указывает, что содержимое файла будет интерпретировано двоичным кодом python , расположенным в /usr/bin/python .

Обратите внимание, что строка shebang анализируется ядром, а затем скрипт будет в конечном итоге вызываться как аргумент:

python script_name

Аналогично в случае #!/bin/bash :

bash script_name
    
ответ дан heemayl 04.11.2015 в 22:57
7

Технически это не требует. Для этого требуется путь к среде, в которой выполняется ваш скрипт. Ваши будущие сценарии будут лучше включать / usr / bin / env, а затем указать python. Эти грантополучатели, что ваш скрипт работает в среде python независимо от того, где установлен python. Вы хотите сделать это по соображениям совместимости, вы не можете быть уверены, что следующий человек, которому вы делитесь своим кодом, будет иметь python, установленный в usr / bin / python, или что у них будут разрешения на эти системные файлы.

Вот аналогичный Q & amp; A от переполнения стека .

В сценарии это выглядит так:

#!/usr/bin/env python

Я также вижу некоторую озабоченность в отношении того, как указать python3. Вот как это сделать:

#!/usr/bin/env python3
    
ответ дан j0h 05.11.2015 в 17:50
5

В Linux Python может потребовать или не потребовать строку #! (shebang). Это зависит от того, как обрабатываются коды Python, либо запускать коды в интерактивном режиме Python, либо в сценарии Python.

Интерактивный режим Python позволяет пользователю вводить и запускать коды Python напрямую, что не требует строки shebang. Чтобы запустить интерактивный режим, откройте терминал и введите python для Python 2.X или python3 для Python 3.X.

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Python script позволяет пользователю писать и сохранять коды Python в текстовом файле, а затем запускать коды позже. Это может потребовать или не потребовать строку shebang. Однако есть две известные причины, когда строка shebang требуется для использования скрипта Python в Linux.

  1. для запуска кодов Python в исполняемом скрипте, то есть определяет, как должны выполняться коды и используя какой интерпретатор;

  2. для запуска кодов Python в отношении конкретной версии Python, то есть кодов запуска, совместимых либо с Python 2.X, либо с Python 3.X

Практика с помощью скриптов Python

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

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py содержит только исходный код.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py содержит исходный код и строку shebang.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py содержит то же, что и hello2.py , и выполнил исполняемый файл.

  • hello3.py содержит то же, что и hello2.py , за исключением того, что он предназначен для запуска с Python 3, переименовав первую строку в #!/usr/bin/env python3 .

  • hello3e.py содержит то же, что и hello3.py , и выполнил исполняемый файл.

  • hello3m.py содержит то же, что и hello3.py , и выполнил исполняемый файл, за исключением сохранения в Write Unicode BOM в текстовом редакторе, то есть Mousepad.

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

Метод 1: Запуск с помощью программы Python

Ниже приведены команды и вывод при запуске исходного кода с Python 2 и Python 3.

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Обе версии Python смогли успешно запустить сценарий. Следовательно, строка shebang not требуется при запуске скрипта Python с помощью команды python или python3 .

Способ 2. Запустите сценарий Python

Ниже приведены команды и вывод при запуске исходного кода с помощью строки shebang, которые не адаптированы ни к Python 2, ни к Python 3, включая неисполняемые и исполняемые файлы.

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Первые три сценария потерпели неудачу, потому что эти сценарии не исполняются, независимо от того, есть ли строка shebang или нет (для подтверждения доказательств см. Дополнительный пример ниже). Последние два скрипта имеют строку shebang и исполняются.

По-видимому, скрипт, который был сделан исполняемым, по существу бесполезен без линии shebang. Следовательно, требуется строка shebang, и скрипт должен исполняться при запуске кодов Python в исполняемом скрипте.

Когда shebang не работает

В моем подготовленном и проверенном примере запуск hello3m.py в качестве исполняемого скрипта завершился с ошибкой и возвратил ошибку.

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

Это известное ограничение , что shebang не работает или становится недействительным. Когда файл сохраняется как спецификация Юникода (знак порядка байтов), он будет работать нормально как исполняемый сценарий Python.

Дополнительный пример

Этот дополнительный пример следует рассматривать только как подтверждающее доказательство. Пользователь должен избегать запуска этого примера, хотя результат безвреден.

Я создал другой файл с именем hello1e.py , который содержит то же, что и hello1.py , и выполнил исполняемый файл. Выполнение этого сценария вернуло синтаксическую ошибку.

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token '"Hello from Python %s\n"'
./hello1e.py: line 2: 'sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

При запуске этого скрипта сначала курсор мыши будет заменен на знак плюса и ничего не делает. Синтаксическая ошибка не будет отображаться до тех пор, пока я не щелкнув по окну рабочего стола или терминала. Затем этот скрипт создаст файл sys в том же каталоге, что и скрипт.

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

Файл sys был идентифицирован как файл PostScript без расширения файла. Этот файл можно открыть в средстве просмотра документов, то есть в Evince, и файл фактически содержит скриншот окна, которое я нажал ранее. По моему опыту, файл может быть как несколько мегабайт.

Еще раз, строка shebang требуется, и скрипт должен исполняться при запуске скрипта Python в качестве исполняемого скрипта. В противном случае сценарий будет ошибочным, как описано выше.

Дополнительные примечания

Термин «сделанный исполняемый файл» или «должен быть исполняемым» относится к разрешению на запуск сценария.Это делается путем выполнения команды chmod +x FILENAME в терминале или путем проверки опции «Разрешить запуск этого файла как программы» или что-то подобное в окне Свойства в файловом менеджере.

В то время как другие существующие ответы охватывали почти все, этот ответ использовал другой подход, используя практические примеры для объяснения этого вопроса. Синтаксис кода написан с осторожностью, так что примеры могут выполняться либо с Python 2, либо с Python 3, как есть.

Коды Python были адаптированы из Использование Python в Windows и Использование Python на платформах Unix , с дополнительным однострочным кодом вездесущего «Hello, World!». Программа.

Все коды и команды были полностью протестированы и работают в системе Xubuntu 14.04, где по умолчанию установлены Python 2.7 и Python 3.4.

    
ответ дан clearkimura 14.12.2015 в 19:19
4

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

./[file-to-execute]

И он будет знать, какой файл выполнить его, а не вы сами должны указать что-то вроде:

python ./[file-to-execute].py

Часть #! обычно ссылается на shebang или crunch bang .

    
ответ дан Paranoid Panda 04.11.2015 в 22:53
1

Если у вас установлено несколько версий Python, /usr/bin/env гарантирует, что используемый интерпретатор будет первым в% co_de вашей среды. Альтернативой будет хард-код, например, $PATH ;

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

Это правило применимо только для системы на основе UNIX.

    
ответ дан orvi 19.12.2015 в 14:34