Довольно простой вопрос: в Linux, почему Python требует строки
#!/usr/bin/python
в начале файла Python, так как Windows нет?
Что оно делает? потому что описание "Ссылки на Python" немного расплывчато ...
python myscript.py
вместо этого.
Довольно простой вопрос: в Linux, почему Python требует строки
#!/usr/bin/python
в начале файла Python, так как Windows нет?
Что оно делает? потому что описание "Ссылки на Python" немного расплывчато ...
python myscript.py
вместо этого.
Ответы:
У Python нет таких особых требований к Linux. Это загрузчик программ в Unix / Linux, который использует строку «shebang», как она называется. На самом деле это скорее функция, чем ограничение, но мы вернемся к этому чуть позже. На вики-странице "shebang" есть больше деталей, но я постараюсь дать обзор, а также сравнение с Windows здесь.
Сначала давайте посмотрим на ситуацию в Windows:
.
В случае файлов Python, это обычно .py
..py
файлы должны быть открыты с помощью только что установленного приложения Python (то есть интерпретатора Python)..exe
, а .bat
файлы выполняются как пакетные сценарии Windows..py
файлов python.exe
следует открывать их с помощью другой программы, такой как текстовый редактор notepad.exe
.
python <scriptname>.py
(или написать .bat
файл, чтобы сделать это для вас).Теперь, что произойдет, если в верхней части скрипта Python есть строка Шебанга ( #!/usr/bin/python
или #!/usr/bin/env python
)? Ну, так #
как это строка комментария в Python, интерпретатор Python просто игнорирует ее. Это одна из причин, почему большинство языков сценариев, используемых в мире Unix / Linux, используют #
для запуска строк комментариев.
Поэтому немного ошибочно утверждать, что Windows «не нужна» #!
строка; Окна не вижу в #!
линию, а на самом деле опирается на расширение файла , чтобы сказать ему , что делать. Это имеет пару недостатков:
.py
в конце, чтобы они автоматически распознавались как таковые..py
типа файла, Windows больше не будет автоматически запускать эти сценарии с Python. Обратите внимание, что это может быть сделано непреднамеренно.Теперь давайте посмотрим, как Unix / Linux запускает скрипты:
Первое, что следует отметить, это то, что Unix / Linux, в отличие от Windows, не пытается «открывать» скрипты Python с использованием определенной программы, по крайней мере, концептуально; ОС знает, что скрипт - это нечто, что может быть выполнено из-за чего-то, называемого «бит выполнения» (что выходит за рамки этого ответа). Таким образом, если вы случайно наберете #!/usr/bin/pthon
вместо #!/usr/bin/python
, вы получите сообщение об ошибке, содержащее этот текст:
/usr/bin/pthon: bad interpreter: No such file or directory.
Слово «интерпретатор» дает нам представление о роли линии Шебанга (хотя технически указанная программа может быть чем-то иным, чем интерпретатор, например cat
текстовый редактор). Когда вы пытаетесь выполнить файл, вот что происходит:
#!
, то загрузчик интерпретирует остаток строки shebang (исключая сам shebang) как команду для запуска интерпретатора, с помощью которого содержимое файла запускается как скрипт.Это имеет пару преимуществ:
Наконец, обратите внимание, что Unix / Linux не нуждается в строке shebang для запуска скрипта Python. Вспомните, что на самом деле все, что делает строка shebang, это позволяет загрузчику программы выбрать интерпретатора. Но, как и в Windows, это можно сделать вручную:
python <myscript>
.py2
и .py3
расширения для скриптов Python 2 / Python 3. Таким образом, и Linux (+ x bit), и Windows (расширение файла) нуждаются в метаданных в файловой системе. Основное отличие состоит в том, что бит + x легче теряется при передаче. Это не обязательно обратная сторона.
/usr/bin/i686/python
и /usr/bin/amd64/python
? Совершенно разумно, но это нарушает скрипты Python, которые имеют жестко запрограммированное предположение /usr/bin/python
. Выбор переводчика зависит не от автора сценария, а от пользователя сценария. Автор сценария может выбирать только язык (диалект).
/usr/bin/env
, вместе со скриптами env-setup. Что это за версия для Windows? Запускать regedit
скрипт прямо перед запуском .py
файла, чтобы убедиться, что вы получите нужный интерпретатор?
Указанная вами строка используется, чтобы сообщить компьютеру, какую программу / интерпретатор использовать при непосредственном запуске файла / сценария, и любые аргументы, которые следует передать этой программе при запуске сценария. Это, однако, не требование Python , это требование ядра / системы linux, если вы собираетесь запустить скрипт напрямую (а не передавать его в Python с помощью приведенного ниже синтаксиса).
Это не нужно, если вы собираетесь выполнить python script.py
или подобное. Это необходимо только в том случае, если вы намереваетесь запустить скрипт / файл напрямую, без предоставления интерпретатора для использования (например, python
).
Для сценария Bash это будет выглядеть примерно так:
#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;
Это будет указывать системе, что при ее запуске она должна выполняться на /bin/bash
одном из языков оболочки / сценариев оболочки в системе.
Для кода 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 и т. Д.)
Выделение синтаксиса выше зависит от языка в каждом разделе, хотя это не имеет значения.
#!/bin/bash -x
, #!/usr/bin/perl -lan
и т. Д.).
/usr/bin/env python
для получения правильного питона.
env
, но проблема не в количестве аргументов: #!/usr/bin/perl -l -a -n
имеет три аргумента, но работает. Хотя, опять же, я не в состоянии справиться с точной проблемой.
./
. Другими словами, просто python filename.py
или bash script.sh
будет работать нормально. Единственная причина для включения ./
- в имени команды, когда вы хотите, чтобы оболочка не выполняла поиск $PATH
(который, вероятно, не найдет файлы в текущем каталоге), а указала путь, который вы указали как есть. Но это не относится к аргументам команды.
env
остальные аргументы из ядра. Можно предположить, что все они являются одним большим аргументом без разбивки по пробелам. Извините за артикуляцию, я уже не помню подробностей этого
Линия:
#!/usr/bin/python
называется «шебанг» и указывает путь к двоичному файлу интерпретатора, который будет использоваться для интерпретации остальных команд в файле. Обычно это первая строка скрипта.
Таким образом, строка #!/usr/bin/python
указывает, что содержимое файла будет интерпретироваться python
двоичным файлом, расположенным в /usr/bin/python
.
Обратите внимание, что строка shebang анализируется ядром, и затем сценарий будет в конечном итоге вызываться в качестве аргумента:
python script_name
Аналогично в случае #!/bin/bash
:
bash script_name
shebang
. Поскольку слово образовано из «хэш» и «взрыв», ваше написание не очень ясно, так как похоже, что это сочетание «она» и «взрыв».
hashbang
( #
= "hash") или shebang
( #
= "sharp"), в зависимости от того, как вы назовете #
персонажа. Тем не менее, shebang
это действительно чаще. @KyleStrand
Технически это не требуется. Требуется путь к среде, в которой выполняется ваш скрипт. Ваши будущие сценарии лучше включить / usr / bin / env, а затем указать python. Это дает право на то, что ваш скрипт запускается в среде python независимо от того, где установлен python. Вы хотите сделать это по причинам совместимости, вы не можете быть уверены, что у следующего человека, с которым вы поделитесь своим кодом, будет установлен python в usr / bin / python, или что у них будут права доступа к этим системным файлам.
Вот аналогичные вопросы и ответы от переполнения стека .
Как это выглядит в вашем скрипте:
#!/usr/bin/env python
Я также вижу некоторую озабоченность по поводу того, как указать python3. Вот как это сделать:
#!/usr/bin/env python3
В 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 позволяет пользователю писать и сохранять коды Python в виде простого текстового файла, а затем запускать коды позже. Это может или не может потребовать линии Шебанга. Однако есть две известные причины, по которым строка shebang требуется для использования скрипта Python в Linux.
запускать коды Python в исполняемом скрипте, т.е. определять, как коды должны выполняться и какой интерпретатор использовать;
запускать коды Python для определенной версии Python, т.е. запускать коды, совместимые только с Python 2.X или Python 3.X
Ниже приведен список и содержимое файлов, которые я использовал, чтобы показать случаи, когда #!
строка (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
содержит исходный код и строку Шебанга.
#!/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
опцией в текстовом редакторе, т.е.
Помимо этого, пользователю будут представлены два метода для запуска сценариев 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 не требуется при запуске скрипта Python с помощью python
или python3
команды.
Ниже приведены команды и вывод при запуске исходного кода со строкой 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, и сценарий должен быть исполняемым при запуске кодов Python в исполняемом сценарии.
В моем подготовленном и протестированном примере выполнение hello3m.py
в качестве исполняемого скрипта завершилось ошибкой и вернуло ошибку.
$ ./hello3m.py
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory
Это известное ограничение : шебанг не работает или становится недействительным. Когда файл сохраняется как Unicode BOM (Byte Order Mark), он не сможет нормально работать как исполняемый скрипт 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.
Это означает, что когда этот файл исполняется, ваш компьютер знает, как выполнить его с программой /usr/bin/python
, это то, как вы говорите об этом, помимо другого языка, такого как bash, где вы будете делать #!/bin/bash
. Это так, что вы можете просто запустить:
./[file-to-execute]
И он будет знать, с каким файлом его выполнять, а вам самим не придется указывать что-то вроде:
python ./[file-to-execute].py
Эта #!
часть обычно называется шебанг или хруст .
Если у вас установлено несколько версий Python, /usr/bin/env
убедитесь, что используемый интерпретатор является первым в вашей среде $PATH
. Альтернативой было бы жестко закодировать что-то вроде #!/usr/bin/python
;
В Unix исполняемый файл, предназначенный для интерпретации, может указывать, какой интерпретатор использовать, имея #!
в начале первой строки, за которым следует интерпретатор (и любые флаги, которые могут ему понадобиться).
Это правило применимо только для систем на основе UNIX.
полезно для таких ОС, как Linux, где Python 2.x по-прежнему является стандартом, но большинство людей также скачивают 3.x.
2.x будет работать по умолчанию. Итак, мой код 3.x, я префикс #! / Usr / bin / env python3, чтобы 3.x запускал код. Я даже могу указать вплоть до незначительной ревизии (python 3.xyz), если я выбрал бета-версии или просто несколько более старые версии.
.
), чтобы определить, какой это тип файла. Даже Windows отходит от этого: изучите первые несколько строк файла Microsoft Word, и он скажет, что на самом деле это файл Microsoft Word.