У меня есть скрипт 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). Это требует, чтобы вы нашли способ написать такой двухъязыковой скрипт для вашего целевого языка. В Perl это известно как 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"
это строка, которая имеет значение true, когда интерпретируется как логическое значение, так что это if
инструкция, которая всегда верна и выполняет строковый литерал.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Код Rosetta имеет такие двухъязыковые скрипты на нескольких других языках.
PYTHONPATH
переменную env для загрузки модулей из нестандартного расположения для CGI-скрипта в системе, к которой у меня не было root-доступа. Спасатель жизни. Еще раз спасибо.
Строки Shebang не подвергаются расширению переменных, поэтому вы не можете использовать их так, $FOO/MyCustomPython
как если бы вы искали исполняемый файл с именем dollar-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, ...). Все остальные имена переменных должны содержать хотя бы одну строчную букву. Это соглашение позволяет избежать случайного переопределения внешних и внутренних переменных. Кроме того, не используйте расширения для своих сценариев. Скрипты определяют новые команды, которые вы можете запускать, а команды обычно не имеют расширений.
Вы можете либо использовать абсолютный путь к пользовательской установке Python, либо вы можете указать его $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, которую нельзя импортировать как модуль в системный python.
Если вы можете заменить $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...