Коли я використовую shebang #!/usr/bin/env pythonдля запуску сценарію, як система знає, який pythonвикористовувати? якщо я шукаю pythonбін-шлях у змінних оточення, я нічого не знайду.
env | grep -i python
Коли я використовую shebang #!/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.
Рядок shebang (від "різкого удару", тобто #!) обробляється ядром. Ядро не хоче знати про такі змінні середовища, як 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по whichсуті є eval версія .
Правильно, так що запустіть:
env | grep PATH
Ваш $ PATH - це список каталогів. Unix буде проходити через цей список каталогів по порядку, поки не знайде "python".
Ви можете побачити, який каталог він знайде, за допомогою команди "який":
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']).