Когда я использую шебанг #!/usr/bin/env python
для запуска скрипта, как система узнает, какой python
использовать? если я ищу python
путь бин в переменных среды, я ничего не нахожу.
env | grep -i python
Когда я использую шебанг #!/usr/bin/env python
для запуска скрипта, как система узнает, какой python
использовать? если я ищу python
путь бин в переменных среды, я ничего не нахожу.
env | grep -i python
Ответы:
Шебанг ожидает, что будет использован полный путь к интерпретатору, поэтому следующий синтаксис будет неправильным:
#!python
Установка полного пути, как это может работать:
#!/usr/local/bin/python
но было бы не портативная , как питон может быть установлен /bin
, /opt/python/bin
или где -то другое место.
С помощью env
#!/usr/bin/env python
это метод, позволяющий переносимым способом указать ОС полный путь, эквивалентный тому, где python
он впервые находится в PATH
.
Линия Шебанга (от «резкого взрыва», т.е. #!
) обрабатывается ядром. Ядро не хочет знать о переменных среды, таких как PATH
. Таким образом, имя в строке shebang должно быть абсолютным путем к исполняемому файлу. Вы также можете указать дополнительный аргумент для передачи в этот исполняемый файл перед именем скрипта (с системно-зависимыми ограничениями я не буду здесь вдаваться). Например, для скрипта Python вы можете указать
#!/usr/bin/python
в первой строке, и когда вы выполняете скрипт, ядро будет фактически выполнено /usr/bin/python /path/to/script
. Но это не удобно: вам нужно указать полный путь к команде. Что делать , если у вас есть python
в /usr/bin
на некоторых машинах и /usr/local/bin
на других? Или вы хотите установить PATH
для /home/joe/opt/python-2.5/bin
того, чтобы использовать конкретную версию Python? Поскольку ядро не будет выполнять PATH
поиск за вас, идея состоит в том, чтобы заставить ядро запустить команду, которая, в свою очередь, ищет нужный интерпретатор в PATH
:
#!/fixed/path/to/path-lookup-command python
Это path-lookup-command
должно взять имя исполняемого файла в качестве аргумента, найти его PATH
и выполнить: ядро запустится /fixed/path/to/path-lookup-command python /path/to/script
. Как это бывает, env
команда делает именно это. Его основная цель - запустить команду в другой среде, но, поскольку она ищет имя команды $PATH
, она идеально подходит для нашей цели.
Хотя это официально не гарантировано, исторические системы Unix при условии , env
в /usr/bin
, и современные системы сохранили это место именно из-за широкого использования #!/usr/bin/env
. Таким образом, на практике способ указать, что скрипт должен выполняться любимым интерпретатором Python пользователя,
#!/usr/bin/env python
env
и which
? поскольку он также получит наиболее подходящий исполняемый файл из моей среды PATH.
which
находит исполняемый файл и печатает его путь. env
находит программу, указанную в первом аргументе, и выполняет ее, передавая оставшиеся аргументы.
env
это eval версия по which
существу.
Хорошо, так что беги:
env | grep PATH
Ваш $ PATH - это список каталогов. Unix будет проходить этот список каталогов по порядку, пока не найдет «python».
Вы можете увидеть, какой каталог он находит с помощью команды which:
which python
sys.path
между активированными env $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) и ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
).