Ответ ниже утверждает, что это просто строка комментария. Это не всегда так. У меня есть «Привет, мир!» CGI-скрипт (.py), который будет запускаться и отображать веб-страницу #!/usr/bin/env pythonтолько вверху.
Я посещал этот пост так много раз за 7 лет, потому что иногда забывал о hashbang env.
BugHunterUK
Ответы:
1085
Если у вас установлено несколько версий Python, /usr/bin/envубедитесь, что используемый интерпретатор является первым в вашей среде $PATH. Альтернативой было бы жестко закодировать что-то вроде#!/usr/bin/python ; это нормально, но менее гибко.
В Unix исполняемый файл, предназначенный для интерпретации, может указывать, какой интерпретатор использовать, имея #!в начале первой строки, за которым следует интерпретатор (и любые флаги, которые могут ему понадобиться).
Если вы говорите о других платформах, конечно, это правило не применяется (но эта «линия Шебанга» не причиняет вреда и поможет, если вы когда-нибудь скопируете этот скрипт на платформу с базой Unix, такую как Linux, Mac , так далее).
Просто добавить: это применимо, когда вы запускаете его в Unix, делая его исполняемым ( chmod +x myscript.py), а затем запускаете его напрямую: ./myscript.pyвместо простого python myscript.py.
Крейг МакКуин
28
Использование envдает максимальную гибкость в том, что пользователь может выбрать интерпретатор для использования путем изменения PATH. Часто эта гибкость не требуется, хотя и недостатком является то, что Linux, например, не может использовать имя сценария для имени процесса psи возвращается к «python». При упаковке приложений Python для дистрибутивов, например, я бы советовал не использовать env.
Важное предупреждение, возвращаемое значение env в конце концов истекает. Что вряд ли повлияет на вас, если вы запускаете недолговечные процессы. Тем не менее, у меня были процессы, умирающие с сообщением /usr/bin/env: Key has expiredчерез много часов.
Малавердиер
4
@malaverdiere можете ли вы ссылаться на какие-либо ресурсы, которые объясняют это поведение истечения срока действия? Я не могу их найти.
В вычислениях шебанг (также называемый хэш-бэнг, хэшплинг, фунт-бэнг или хруст-бэнг) относится к символам "#!" когда они являются первыми двумя символами в директиве интерпретатора в качестве первой строки текстового файла. В Unix-подобной операционной системе загрузчик программы воспринимает присутствие этих двух символов как указание на то, что файл является сценарием, и пытается выполнить этот сценарий, используя интерпретатор, указанный в оставшейся части первой строки файла.
Даже в Windows, где строка shebang не определяет интерпретатор для запуска, вы можете передать опции интерпретатору, указав их в строке shebang. Я считаю полезным хранить общую строку shebang в одноразовых скриптах (например, тех, которые я пишу, отвечая на вопросы по SO), чтобы я мог быстро протестировать их как в Windows, так и в ArchLinux .
Первый оставшийся аргумент указывает имя программы для вызова; ищется по PATHпеременной окружения. Все оставшиеся аргументы передаются в качестве аргументов этой программе.
Легко найти с помощью Google - если кто-то знает ключевые слова («линия Шебанга» имеет важное значение).
Арафангион
14
На самом деле, это объяснение яснее, чем другие ссылки, которые я проверял в Google. Всегда лучше получить 1 параграф объяснения, нацеленного на вопрос, а не читать полное руководство по каждому потенциальному использованию.
@ulidtko: Интересная поисковая система, подумайте над тем, чтобы написать ответ, чтобы вопрос Джона Гарсиаса был лучше.
Арафангион
1
«Даже в Windows, где строка shebang не определяет интерпретатор для запуска, вы можете передать опции интерпретатору, указав их в строке shebang». Это просто ложь; если такое случается, это потому, что сам интерпретатор обрабатывает строку shebang. Если интерпретатор не имеет особого распознавания линий Шебанга, то такого не происходит. Windows ничего не делает со строками Шебанга . «В этом случае вы можете описать пусковую установку python: python.org/dev/peps/pep-0397 .
Kaz
154
Немного расширив остальные ответы, приведу небольшой пример того, как ваши скрипты командной строки могут попасть в неприятности из-за неосторожного использования /usr/bin/envстрок Шебанга:
Разница между локальным и глобальным. Если which pythonвозвращается /usr/bin/python, локальный путь к каталогу может быть жесток: #!/usr/bin/python. Но это менее гибко, чем #!/usr/bin/env pythonглобальное применение.
noobninja
85
Чтобы запустить скрипт на python, нам нужно сказать оболочке три вещи:
Что файл является скриптом
Какой интерпретатор мы хотим выполнить сценарий
Путь указанного переводчика
Шебанг #!выполняет (1.). Шебанг начинается с символа, #потому что #символ является маркером комментария во многих языках сценариев. Поэтому содержимое строки Шебанга автоматически игнорируется интерпретатором.
Команда envвыполняет (2.) и (3.). Чтобы процитировать "Гравитация"
Обычное использование envкоманды - запуск интерпретаторов, используя тот факт, что env будет искать в $ PATH команду, которую ей говорят запустить. Поскольку строка shebang требует указания абсолютного пути, а расположение различных интерпретаторов (perl, bash, python) может сильно различаться, обычно используется:
#!/usr/bin/env perl вместо того, чтобы пытаться угадать, является ли это / bin / perl, / usr / bin / perl, / usr / local / bin / perl, / usr / local / pkg / perl, / fileserver / usr / bin / perl или / home / MrDaniel / usr / bin / perl в системе пользователя ...
С другой стороны, env почти всегда находится в / usr / bin / env. (За исключением случаев, когда это не так; некоторые системы могут использовать / bin / env, но это довольно редкий случай и происходит только в системах, отличных от Linux.)
Вам не нужна эта линия вообще. Система вызовет python, а затем интерпретатор python запустит ваш скрипт.
Но если вы собираетесь использовать: $./myscript.py
Вызывая его напрямую, как обычную программу или скрипт bash, вам нужно написать эту строку, чтобы указать системе, какую программу использовать для ее запуска, (а также сделать ее исполняемой с chmod 755 )
Он читает самые первые байты файла и сравнивает их с #! .
Если сравнение истинно, то остальная часть строки анализируется ядром Linux, которое делает еще один execвызов с путем /usr/bin/env pythonи текущим файлом в качестве первого аргумента:
/usr/bin/env python /path/to/script.py
и это работает для любого языка сценариев, который использует # в качестве символа комментария.
И да, вы можете сделать бесконечный цикл с:
printf '#!/a\n'| sudo tee /a
sudo chmod +x /a
/a
Bash распознает ошибку:
-bash:/a: /a: bad interpreter:Too many levels of symbolic links
#! бывает, что он читается человеком, но это не обязательно.
Если файл начинается с разных байтов, то execсистемный вызов будет использовать другой обработчик. Другой самый важный встроенный обработчик для исполняемых файлов ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, который проверяет байты 7f 45 4c 46(которые также являются человеческими читаемый для .ELF). Давайте подтвердим это, прочитав 4 первых байта /bin/ls, который является исполняемым файлом ELF:
Я не думаю, что POSIX определяет shebangs, однако: https://unix.stackexchange.com/a/346214/32558 , хотя он упоминается в разделах обоснования и в форме «если исполняемые сценарии поддерживаются системой, что-то может случиться». macOS и FreeBSD также, похоже, реализуют это.
PATH поисковая мотивация
Вероятно, одной большой мотивацией для существования шебангов является тот факт, что в Linux мы часто хотим запускать команды так PATHже, как:
basename-of-command
вместо:
/full/path/to/basename-of-command
Но тогда, без механизма shebang, как Linux узнает, как запускать файлы каждого типа?
Жесткое кодирование расширения в командах:
basename-of-command.py
или осуществляя поиск PATH на каждом интерпретаторе:
python basename-of-command
было бы возможно, но это главная проблема, что все ломается, если мы когда-нибудь решим реорганизовать команду на другой язык.
Технически, в Python это просто строка комментария.
Эта строка используется только если вы запускаете скрипт py из оболочки (из командной строки). Это известно как " Шебанг !" и используется в различных ситуациях, а не только в сценариях Python.
Здесь он указывает оболочке запустить определенную версию Python (чтобы позаботиться об остальной части файла.
Шебанг - это концепция Unix. Стоит упомянуть, что он работает и в Windows, если вы установили пусковую установку Pythonpy.exe . Это часть стандартной установки Python.
Флорисла
38
Основная причина сделать это - сделать скрипт переносимым между средами операционной системы.
Например, в mingw скрипты на python используют:
#!/c/python3k/python
и в дистрибутиве GNU / Linux это либо:
#!/usr/local/bin/python
или
#!/usr/bin/python
и под самой лучшей коммерческой системой Unix SW / HW из всех (OS / X) это:
#!/Applications/MacPython 2.5/python
или на FreeBSD:
#!/usr/local/bin/python
Однако все эти различия могут сделать сценарий переносимым через все:
Под MacOSX это тоже так /usr/bin/python. Под Linux Python, установленный системой, также почти наверняка /usr/bin/python(я больше ничего не видел, и это не имело бы никакого смысла). Обратите внимание, что могут быть системы, которые не имеют /usr/bin/env.
Альберт
1
Если вы используете OSX и используете Homebrew и следуете инструкциям по умолчанию, он будет находиться под #! / Usr / local / bin / python
Will
@ Jean-PaulCalderone: см. Ответ Саадж ниже.
pydsigner
Обновление на 2018 год: Bare pythonне так переносим, это дистрибутив Python по умолчанию. Arch Linux по умолчанию установлен на Python 3 долгое время, и, возможно, дистрибутивы тоже думают об этом, потому что Python 2 поддерживается только до 2020 года.
mati865
22
Вероятно, имеет смысл подчеркнуть одну вещь, которую большинство пропустило, что может помешать немедленному пониманию. Когда вы печатаете pythonв терминале, вы обычно не указываете полный путь. Вместо этого исполняемый файл ищется в PATHпеременной окружения. В свою очередь, когда вы хотите выполнить программу на Python напрямую, /path/to/app.pyнужно указать оболочке, какой интерпретатор использовать (через hashbang , что другие авторы объясняют выше).
Hashbang ожидает полного пути к переводчику. Таким образом, чтобы запустить вашу программу на Python напрямую, вы должны указать полный путь к двоичному файлу Python, который значительно варьируется, особенно с учетом использования virtualenv . Для решения переносимости используется трюк с /usr/bin/env. Последний изначально предназначен для изменения среды на месте и запуска в ней команды. Если никаких изменений не предусмотрено, команда запускается в текущей среде, что фактически приводит к тому жеPATH поиску, что и уловка.
Он просто указывает, какой интерпретатор вы хотите использовать. Чтобы понять это, создайте файл через терминал, выполнив touch test.py, затем введите в этот файл следующее:
#!/usr/bin/env python3print"test"
и сделать, chmod +x test.pyчтобы сделать ваш скрипт исполняемым. После этого, когда вы делаете, ./test.pyвы должны получить сообщение об ошибке:
File"./test.py", line 2print"test"^SyntaxError:Missing parentheses in call to 'print'
потому что python3 не поддерживает оператор печати.
Теперь перейдите и измените первую строку вашего кода на:
#!/usr/bin/env python2
и он будет работать, печатая testна стандартный вывод, потому что python2 поддерживает оператор печати. Итак, теперь вы узнали, как переключаться между интерпретаторами сценариев.
Мне кажется, что файлы без этой строки работают одинаково.
Если так, то, возможно, вы используете программу Python в Windows? Windows не использует эту строку - вместо этого она использует расширение имени файла для запуска программы, связанной с расширением файла.
Однако в 2011 году был разработан «модуль запуска Python», который (в некоторой степени) имитирует такое поведение Linux для Windows. Это ограничивается только выбором запускаемого интерпретатора Python - например, для выбора между Python 2 и Python 3 в системе, где установлены оба. Модуль запуска по выбору устанавливается как py.exeпри установке Python и может быть связан с .pyфайлами, так что модуль запуска проверяет эту строку и, в свою очередь, запускает указанную версию интерпретатора Python.
Я сделал ошибку, не имея строки, и использовал python script.py, и однажды я просто сделал ./myscript.py, и все перестало работать, а затем понял, что система ищет файл как сценарий оболочки вместо сценария python.
Гуагуа
8
Это означает больше исторической информации, чем «реального» ответа.
Помните , что еще в день вы имели МНОГО UNIX - подобные операционные системам , в которых дизайнеры все имел свое собственное представление о том, где положить вещи, а иногда и не включает в себя Python, Perl, Bash, или много другого GNU / Open Source материала на все ,
Это было даже верно для разных дистрибутивов Linux. В Linux - pre-FHS [1] - у вас может быть python в / usr / bin / или / usr / local / bin /. Или, возможно, он не был установлен, поэтому вы создали свой собственный и поместили его в ~ / bin
Solaris был худшим из всех, над которыми я когда-либо работал, частично как переход с Berkeley Unix на System V. Вы можете оказаться с вещами в / usr /, / usr / local /, / usr / ucb, / opt / и т.д. Это может сделать для некоторых действительно длинных путей. У меня есть воспоминания о том, как Sunfreeware.com устанавливал каждый пакет в свой собственный каталог, но я не могу вспомнить, содержит ли он символические ссылки в / usr / bin или нет.
О, и иногда / usr / bin находился на NFS-сервере [2].
Так что envутилита была разработана, чтобы обойти это.
Тогда вы могли бы написать, #!/bin/env interpreterи, пока путь был верным, у вещей был разумный шанс бежать. Конечно, разумно (для Python и Perl) означало, что вы также установили соответствующие переменные среды. Для bash / ksh / zsh это просто сработало.
Это было важно, потому что люди передавали скрипты оболочки (такие как perl и python), и если вы жестко запрограммировали / usr / bin / python на вашей рабочей станции Red Hat Linux, то это будет плохо работать на SGI ... ну, нет Я думаю, что IRIX поставил Python в нужное место. Но на станции Sparc он может вообще не работать.
Я скучаю по своей станции sparc. Но не много. Хорошо, теперь ты заставляешь меня троллить по E-Bay. Bastages.
Например, если вы выполняете свой сценарий в виртуальной среде, venvто выполнение which pythonво время работы venvпокажет путь к интерпретатору Python:
~/Envs/venv/bin/python
Обратите внимание, что имя виртуальной среды встроено в путь к интерпретатору Python. Поэтому жесткое кодирование этого пути в вашем скрипте вызовет две проблемы:
Если вы загружаете скрипт в репозиторий, вы заставляете других пользователей иметь такое же имя виртуальной среды . Это если они сначала идентифицируют проблему.
Вы не сможете запустить скрипт в нескольких виртуальных средах, даже если у вас были все необходимые пакеты в других виртуальных средах.
Поэтому, чтобы добавить к ответу Джонатана , идеальный шебанг#!/usr/bin/env python не только переносимость между операционными системами, но и переносимость между виртуальными средами!
Чтобы допустить различия между платформами, весь новый код, который должен вызывать интерпретатор Python, не должен указывать python, а должен указывать либо python2, либо python3 (или более конкретные версии python2.x и python3.x; см. Примечания по миграции ). , Это различие следует делать в шебангах, при вызове из сценария оболочки, при вызове через вызов system () или при вызове в любом другом контексте.
Это позволяет вам выбрать исполняемый файл, который вы хотите использовать; что очень удобно, если, возможно, у вас есть несколько установок Python и разные модули в каждом и вы хотите выбрать. например
#!/bin/sh## Choose the python we need. Explanation:# a) '''\' translates to \ in shell, and starts a python multi-line string# b) "" strings are treated as string concat by python, shell ignores them# c) "true" command ignores its arguments# c) exit before the ending ''' so the shell reads no further# d) reset set docstrings to ignore the multiline comment code#"true"'''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3
if [ -x $PREFERRED_PYTHON ]; then
echo Using preferred python $ALTERNATIVE_PYTHON
exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
echo Using alternative python $ALTERNATIVE_PYTHON
exec $ALTERNATIVE_PYTHON "$0" "$@"
else
echo Using fallback python $FALLBACK_PYTHON
exec python3 "$0" "$@"
fi
exit 127
'''
__doc__ ="""What this file does"""print(__doc__)import platform
print(platform.python_version())
Строка #!/bin/bash/python3или #!/bin/bash/pythonуказывает, какой компилятор Python использовать. У вас может быть установлено несколько версий Python. Например, a.py:
#!/bin/bash/python3print("Hello World")
это скрипт на python3, а b.py:
#!/bin/bash/pythonprint"Hello World"
является скриптом Python 2.x
Чтобы запустить ./a.pyили ./b.pyиспользовать этот файл , вам необходимо дать привилегии выполнения файлов заранее, иначе выполнение приведет к Permission deniedошибке.
Для предоставления разрешения на исполнение,
#!/usr/bin/env python
только вверху.Ответы:
Если у вас установлено несколько версий Python,
/usr/bin/env
убедитесь, что используемый интерпретатор является первым в вашей среде$PATH
. Альтернативой было бы жестко закодировать что-то вроде#!/usr/bin/python
; это нормально, но менее гибко.В Unix исполняемый файл, предназначенный для интерпретации, может указывать, какой интерпретатор использовать, имея
#!
в начале первой строки, за которым следует интерпретатор (и любые флаги, которые могут ему понадобиться).Если вы говорите о других платформах, конечно, это правило не применяется (но эта «линия Шебанга» не причиняет вреда и поможет, если вы когда-нибудь скопируете этот скрипт на платформу с базой Unix, такую как Linux, Mac , так далее).
источник
chmod +x myscript.py
), а затем запускаете его напрямую:./myscript.py
вместо простогоpython myscript.py
.env
дает максимальную гибкость в том, что пользователь может выбрать интерпретатор для использования путем изменения PATH. Часто эта гибкость не требуется, хотя и недостатком является то, что Linux, например, не может использовать имя сценария для имени процессаps
и возвращается к «python». При упаковке приложений Python для дистрибутивов, например, я бы советовал не использоватьenv
.py
Launcher может использовать строку Shebang на Windows. Он включен в Python 3.3 или может быть установлен независимо ./usr/bin/env: Key has expired
через много часов.Это называется линией Шебанга . Как объясняется запись в Википедии :
Смотрите также запись FAQ по Unix .
Даже в Windows, где строка shebang не определяет интерпретатор для запуска, вы можете передать опции интерпретатору, указав их в строке shebang. Я считаю полезным хранить общую строку shebang в одноразовых скриптах (например, тех, которые я пишу, отвечая на вопросы по SO), чтобы я мог быстро протестировать их как в Windows, так и в ArchLinux .
Утилита окр позволяет выполнить команду на пути:
источник
Немного расширив остальные ответы, приведу небольшой пример того, как ваши скрипты командной строки могут попасть в неприятности из-за неосторожного использования
/usr/bin/env
строк Шебанга:Модуль json не существует в Python 2.5.
Один из способов защиты от подобных проблем - использовать версионные имена команд python, которые обычно устанавливаются с большинством питонов:
Если вам просто нужно различать Python 2.x и Python 3.x, последние выпуски Python 3 также предоставляют
python3
имя:источник
which python
возвращается/usr/bin/python
, локальный путь к каталогу может быть жесток:#!/usr/bin/python
. Но это менее гибко, чем#!/usr/bin/env python
глобальное применение.Чтобы запустить скрипт на python, нам нужно сказать оболочке три вещи:
Шебанг
#!
выполняет (1.). Шебанг начинается с символа,#
потому что#
символ является маркером комментария во многих языках сценариев. Поэтому содержимое строки Шебанга автоматически игнорируется интерпретатором.Команда
env
выполняет (2.) и (3.). Чтобы процитировать "Гравитация"источник
Возможно, ваш вопрос в этом смысле:
Если вы хотите использовать:
$python myscript.py
Вам не нужна эта линия вообще. Система вызовет python, а затем интерпретатор python запустит ваш скрипт.
Но если вы собираетесь использовать:
$./myscript.py
Вызывая его напрямую, как обычную программу или скрипт bash, вам нужно написать эту строку, чтобы указать системе, какую программу использовать для ее запуска, (а также сделать ее исполняемой с
chmod 755
)источник
exec
Системный вызов в Linux ядро понимает shebangs (#!
) изначальноКогда вы делаете на Bash:
в Linux это вызывает
exec
системный вызов с путем./something
.Эта строка ядра вызывается для файла, переданного по адресу
exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25.Он читает самые первые байты файла и сравнивает их с
#!
.Если сравнение истинно, то остальная часть строки анализируется ядром Linux, которое делает еще один
exec
вызов с путем/usr/bin/env python
и текущим файлом в качестве первого аргумента:и это работает для любого языка сценариев, который использует
#
в качестве символа комментария.И да, вы можете сделать бесконечный цикл с:
Bash распознает ошибку:
#!
бывает, что он читается человеком, но это не обязательно.Если файл начинается с разных байтов, то
exec
системный вызов будет использовать другой обработчик. Другой самый важный встроенный обработчик для исполняемых файлов ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, который проверяет байты7f 45 4c 46
(которые также являются человеческими читаемый для.ELF
). Давайте подтвердим это, прочитав 4 первых байта/bin/ls
, который является исполняемым файлом ELF:вывод:
Поэтому, когда ядро видит эти байты, оно берет файл ELF, правильно помещает его в память и запускает новый процесс с ним. Смотрите также: Как ядро получает исполняемый двоичный файл, работающий под Linux?
Наконец, вы можете добавить свои собственные обработчики shebang с
binfmt_misc
механизмом. Например, вы можете добавить пользовательский обработчик для.jar
файлов . Этот механизм даже поддерживает обработчики по расширению файла. Другое приложение - для прозрачного запуска исполняемых файлов другой архитектуры с QEMU .Я не думаю, что POSIX определяет shebangs, однако: https://unix.stackexchange.com/a/346214/32558 , хотя он упоминается в разделах обоснования и в форме «если исполняемые сценарии поддерживаются системой, что-то может случиться». macOS и FreeBSD также, похоже, реализуют это.
PATH
поисковая мотивацияВероятно, одной большой мотивацией для существования шебангов является тот факт, что в Linux мы часто хотим запускать команды так
PATH
же, как:вместо:
Но тогда, без механизма shebang, как Linux узнает, как запускать файлы каждого типа?
Жесткое кодирование расширения в командах:
или осуществляя поиск PATH на каждом интерпретаторе:
было бы возможно, но это главная проблема, что все ломается, если мы когда-нибудь решим реорганизовать команду на другой язык.
Шебангс прекрасно решает эту проблему.
источник
Технически, в Python это просто строка комментария.
Эта строка используется только если вы запускаете скрипт py из оболочки (из командной строки). Это известно как " Шебанг !" и используется в различных ситуациях, а не только в сценариях Python.
Здесь он указывает оболочке запустить определенную версию Python (чтобы позаботиться об остальной части файла.
источник
py.exe
. Это часть стандартной установки Python.Основная причина сделать это - сделать скрипт переносимым между средами операционной системы.
Например, в mingw скрипты на python используют:
и в дистрибутиве GNU / Linux это либо:
или
и под самой лучшей коммерческой системой Unix SW / HW из всех (OS / X) это:
или на FreeBSD:
Однако все эти различия могут сделать сценарий переносимым через все:
источник
/usr/bin/python
. Под Linux Python, установленный системой, также почти наверняка/usr/bin/python
(я больше ничего не видел, и это не имело бы никакого смысла). Обратите внимание, что могут быть системы, которые не имеют/usr/bin/env
.python
не так переносим, это дистрибутив Python по умолчанию. Arch Linux по умолчанию установлен на Python 3 долгое время, и, возможно, дистрибутивы тоже думают об этом, потому что Python 2 поддерживается только до 2020 года.Вероятно, имеет смысл подчеркнуть одну вещь, которую большинство пропустило, что может помешать немедленному пониманию. Когда вы печатаете
python
в терминале, вы обычно не указываете полный путь. Вместо этого исполняемый файл ищется вPATH
переменной окружения. В свою очередь, когда вы хотите выполнить программу на Python напрямую,/path/to/app.py
нужно указать оболочке, какой интерпретатор использовать (через hashbang , что другие авторы объясняют выше).Hashbang ожидает полного пути к переводчику. Таким образом, чтобы запустить вашу программу на Python напрямую, вы должны указать полный путь к двоичному файлу Python, который значительно варьируется, особенно с учетом использования virtualenv . Для решения переносимости используется трюк с
/usr/bin/env
. Последний изначально предназначен для изменения среды на месте и запуска в ней команды. Если никаких изменений не предусмотрено, команда запускается в текущей среде, что фактически приводит к тому жеPATH
поиску, что и уловка.Исходник из unix stackexchange
источник
Это соглашение оболочки, которое сообщает оболочке, какая программа может выполнить скрипт.
разрешает путь к двоичному файлу Python.
источник
Рекомендуемый способ, предложенный в документации:
от http://docs.python.org/py3k/tutorial/interpreter.html#executable-python-scripts
источник
Вы можете попробовать эту проблему, используя virtualenv
Вот test.py
Создавать виртуальные среды
активируйте каждую среду, затем проверьте различия
источник
Он просто указывает, какой интерпретатор вы хотите использовать. Чтобы понять это, создайте файл через терминал, выполнив
touch test.py
, затем введите в этот файл следующее:и сделать,
chmod +x test.py
чтобы сделать ваш скрипт исполняемым. После этого, когда вы делаете,./test.py
вы должны получить сообщение об ошибке:потому что python3 не поддерживает оператор печати.
Теперь перейдите и измените первую строку вашего кода на:
и он будет работать, печатая
test
на стандартный вывод, потому что python2 поддерживает оператор печати. Итак, теперь вы узнали, как переключаться между интерпретаторами сценариев.источник
Если так, то, возможно, вы используете программу Python в Windows? Windows не использует эту строку - вместо этого она использует расширение имени файла для запуска программы, связанной с расширением файла.
Однако в 2011 году был разработан «модуль запуска Python», который (в некоторой степени) имитирует такое поведение Linux для Windows. Это ограничивается только выбором запускаемого интерпретатора Python - например, для выбора между Python 2 и Python 3 в системе, где установлены оба. Модуль запуска по выбору устанавливается как
py.exe
при установке Python и может быть связан с.py
файлами, так что модуль запуска проверяет эту строку и, в свою очередь, запускает указанную версию интерпретатора Python.источник
$ python myscript.py
.Это означает больше исторической информации, чем «реального» ответа.
Помните , что еще в день вы имели МНОГО UNIX - подобные операционные системам , в которых дизайнеры все имел свое собственное представление о том, где положить вещи, а иногда и не включает в себя Python, Perl, Bash, или много другого GNU / Open Source материала на все ,
Это было даже верно для разных дистрибутивов Linux. В Linux - pre-FHS [1] - у вас может быть python в / usr / bin / или / usr / local / bin /. Или, возможно, он не был установлен, поэтому вы создали свой собственный и поместили его в ~ / bin
Solaris был худшим из всех, над которыми я когда-либо работал, частично как переход с Berkeley Unix на System V. Вы можете оказаться с вещами в / usr /, / usr / local /, / usr / ucb, / opt / и т.д. Это может сделать для некоторых действительно длинных путей. У меня есть воспоминания о том, как Sunfreeware.com устанавливал каждый пакет в свой собственный каталог, но я не могу вспомнить, содержит ли он символические ссылки в / usr / bin или нет.
О, и иногда / usr / bin находился на NFS-сервере [2].
Так что
env
утилита была разработана, чтобы обойти это.Тогда вы могли бы написать,
#!/bin/env interpreter
и, пока путь был верным, у вещей был разумный шанс бежать. Конечно, разумно (для Python и Perl) означало, что вы также установили соответствующие переменные среды. Для bash / ksh / zsh это просто сработало.Это было важно, потому что люди передавали скрипты оболочки (такие как perl и python), и если вы жестко запрограммировали / usr / bin / python на вашей рабочей станции Red Hat Linux, то это будет плохо работать на SGI ... ну, нет Я думаю, что IRIX поставил Python в нужное место. Но на станции Sparc он может вообще не работать.
Я скучаю по своей станции sparc. Но не много. Хорошо, теперь ты заставляешь меня троллить по E-Bay. Bastages.
[1] Стандарт иерархии файловой системы. https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
[2] Да, и иногда люди все еще делают подобные вещи. И нет, я не носил на поясе ни репы, ни лука.
источник
Например, если вы выполняете свой сценарий в виртуальной среде,
venv
то выполнениеwhich python
во время работыvenv
покажет путь к интерпретатору Python:~/Envs/venv/bin/python
Обратите внимание, что имя виртуальной среды встроено в путь к интерпретатору Python. Поэтому жесткое кодирование этого пути в вашем скрипте вызовет две проблемы:
Поэтому, чтобы добавить к ответу Джонатана , идеальный шебанг
#!/usr/bin/env python
не только переносимость между операционными системами, но и переносимость между виртуальными средами!источник
Учитывая проблемы переносимости между
python2
иpython3
, вы всегда должны указывать любую версию, если ваша программа не совместима с обеими.Некоторые дистрибутивы поставляются
python
слинкованы вpython3
то время как сейчас - не полагаться наpython
существеpython2
.Это подчеркивается ПКП 394 :
источник
Он сообщает интерпретатору, с какой версией python запускать программу, если у вас несколько версий python.
источник
Это позволяет вам выбрать исполняемый файл, который вы хотите использовать; что очень удобно, если, возможно, у вас есть несколько установок Python и разные модули в каждом и вы хотите выбрать. например
источник
Строка
#!/bin/bash/python3
или#!/bin/bash/python
указывает, какой компилятор Python использовать. У вас может быть установлено несколько версий Python. Например,a.py:
это скрипт на python3, а
b.py:
является скриптом Python 2.x
Чтобы запустить
./a.py
или./b.py
использовать этот файл , вам необходимо дать привилегии выполнения файлов заранее, иначе выполнение приведет кPermission denied
ошибке.Для предоставления разрешения на исполнение,
источник
это говорит сценарию, где находится каталог python!
источник