У меня есть скрипт 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...