У мене є сценарій Python, який потрібно запустити з певною установкою python. Чи є спосіб виготовити шебанг, щоб він працював $FOO/bar/MyCustomPython
?
У мене є сценарій Python, який потрібно запустити з певною установкою python. Чи є спосіб виготовити шебанг, щоб він працював $FOO/bar/MyCustomPython
?
Відповіді:
Лінія шебангу дуже обмежена. У багатьох варіантах unix (включаючи Linux) ви можете мати лише два слова: команду та один аргумент. Також часто існує обмеження довжини.
Загальне рішення - написати невелику оболонку-оболонку. Назвіть сценарій Python foo.py
та поставте скрипт оболонки поруч foo.py
і зателефонуйте foo
. Цей підхід не вимагає особливого заголовка сценарію Python.
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
Ще один спокусливий підхід - написати скрипт для обгортки, як описаний вище, і поставити #!/path/to/wrapper/script
як сценарій shebang на сценарій Python. Однак більшість юніорів не підтримують ланцюжок сценаріїв shebang, тому це не спрацює.
Якщо ви MyCustomPython
знаходилися в $PATH
, ви можете використовувати його env
для пошуку:
#!/usr/bin/env MyCustomPython
import …
Ще один підхід полягає в тому, щоб зробити скрипт дійсним сценарієм оболонки (який завантажує правильний інтерпретатор Python на себе) і дійсним сценарієм на цільовій мові (тут Python). Це вимагає, щоб ви знайшли спосіб написати такий двомовний скрипт для вашої цільової мови. У Перлі це відомо як if $running_under_some_shell
.
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Ось один із способів досягти такого ж ефекту в Python. У оболонці "true"
- це true
утиліта, яка ігнорує її аргументи (дві односимвольні рядки :
та '
) та повертає справжнє значення. У Python "true"
- це рядок, який є істинним, коли його інтерпретують як булевий, так що це if
інструкція, яка завжди відповідає дійсності та виконує літеральний рядок.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Код Розетти має такі двомовні скрипти на кількох інших мовах.
PYTHONPATH
змінної env для завантаження модулів з нестандартного місця для сценарію CGI в системі, до якої не мав кореневого доступу. Рятувальник життя. Знову дякую.
Рядки Shebang не зазнають змінного розширення, тому ви не можете використовувати так, $FOO/MyCustomPython
як це було б для пошуку виконуваного файлу з назвою долар-FOO -...
Альтернативою є те, щоб ваш shebang вказував на скрипт оболонки як інтерпретатор, і цей скрипт оболонки може потім використовувати змінні середовища для пошуку потрібного та виконувати його.
Приклад: створіть mypython.sh
сценарій у /usr/local/bin
(або будь-який інший каталог у вашому $PATH
) із наступним вмістом:
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
то ви можете використовувати цю хатину лінію , щоб мати Python скрипт виконується через з MyCustomPython
допомогою mypython.sh
:
#!/usr/bin/env mypython.sh
$python
, а не $PYTHON
- за умовою, ми використовуємо великі розміри змінних середовища (PAGER, EDITOR, SHELL ... $PYTHON
у вашому сценарії не є змінною середовища) та внутрішніми змінними оболонок (BASH_VERSION, RANDOM, ...). Усі інші назви змінних повинні містити принаймні одну малу літеру. Ця конвенція дозволяє уникнути випадкових переваг екологічних та внутрішніх змінних. Крім того, не використовуйте розширення для своїх сценаріїв. Сценарії визначають нові команди, які можна виконати, а команди, як правило, не дають розширень.
Ви можете використовувати абсолютний шлях до встановлення призначеного для користувача пітона, або ви можете помістити його в $PATH
і використанні #!/usr/bin/env [command]
. В іншому випадку напишіть обгортку для цього і використовуйте exec
для заміни зображення процесу, як приклад:
#!/bin/bash
exec "$ENV/python" "$@"
Спочатку визначте, чим відрізняється ваша версія Python від стандартного вже встановленого Python (наприклад, додатковий модуль), а потім на початку програми "перемкніть", як називається Python:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
Це повинно дозволяти викликати програму будь-яким іншим екземпляром Python. Я роблю щось подібне для екземпляра із вбудованою бібліотекою sql, яку неможливо імпортувати як модуль у пітоні системи.
Якщо ви можете замінити $FOO
в $FOO/bar/MyCustomPython
конкретних варіантів шляху, ви можете сказати env
притон лінію , де шукати свій власний Python версії, безпосередньо встановивши звичай PATH
в ньому.
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
Редагувати : Здається, працює лише без лапок навколо призначення значення PATH:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
так:PATH=$PATH:/path/to/whatever...