Развертывание Python и переносимость / usr / bin / env - PullRequest
13 голосов
/ 03 сентября 2008

В начале всех моих исполняемых скриптов Python я поставил строку shebang :

#!/usr/bin/env python

Я запускаю эти сценарии в системе, где env python создает среду Python 2.2. Мои сценарии быстро терпят неудачу, потому что у меня есть ручная проверка для совместимой версии Python:

if sys.version_info < (2, 4):
    raise ImportError("Cannot run with Python version < 2.4")

Я не хочу менять строку shebang для каждого исполняемого файла, если это возможно; тем не менее, у меня нет административного доступа к машине, чтобы изменить результат env python, и я не хочу принудительно указывать конкретную версию, как в:

#!/usr/bin/env python2.4

Я бы хотел избежать этого, потому что система может иметь более новую версию, чем Python 2.4, или может иметь Python 2.5, но не Python 2.4.

Какое элегантное решение?

[Edit:] Я не был достаточно конкретен в постановке вопроса - я хотел бы позволить пользователям выполнять сценарии без ручной настройки (например, изменение пути или символическая ссылка в ~/bin и обеспечение того, что ваш PATH имеет ~/bin до пути Python 2.2). Может быть, для предотвращения ручной настройки требуется какая-то утилита распространения?

Ответы [ 5 ]

8 голосов
/ 03 сентября 2008

"env" просто выполняет первое, что находит в переменной PATH env. Чтобы переключиться на другой python, добавьте каталог для исполняемого файла этого питона к пути перед вызовом вашего скрипта.

4 голосов
/ 04 сентября 2008

Довольно хакерское решение - если ваша проверка не удалась, используйте эту функцию (которая, вероятно, могла бы быть значительно улучшена), чтобы определить лучшего доступного интерпретатора, определить, является ли он приемлемым, и если да, перезапустить ваш скрипт с os.system или чем-то подобным Ваш sys.argv использует новый интерпретатор.

import os
import glob
def best_python():
    plist = []
    for i in os.getenv("PATH").split(":"):
        for j in glob.glob(os.path.join(i, "python2.[0-9]")):
             plist.append(os.path.join(i, j))
    plist.sort()
    plist.reverse()
    if len(plist) == 0: return None
    return plist[0]
2 голосов
/ 03 сентября 2008

Если вы запускаете сценарии, вы можете установить переменную PATH так, чтобы она сначала указывала на каталог приватного бина:

$ mkdir ~/bin
$ ln -s `which python2.4` ~/bin/python
$ export PATH=~/bin:$PATH

Затем, когда вы выполните свой скрипт на python, он будет использовать python 2.4. Вам придется изменить свои сценарии входа в систему, чтобы изменить свой путь.

В качестве альтернативы запустите ваш скрипт на python с явным интерпретатором, который вам нужен:

$ /path/to/python2.4 <your script>
0 голосов
/ 04 октября 2013

Вот решение, если вы (1) абсолютно настроены на использование shebangs и (2) можете использовать Autotools в процессе сборки.

Я только вчера обнаружил, что вы можете использовать макрос autoconf AM_PATH_PYTHON, чтобы найти минимальный двоичный файл Python 2 . Как это сделать здесь .

Итак, ваш процесс будет:

  • Выпуск AM_PATH_PYTHON(2.4) в вашем configure.ac
  • Переименуйте все ваши .py сценарии в .py.in (по моему опыту это не смущает vi)
  • Назовите все те скрипты Python, которые вы хотите сгенерировать, с помощью AC_CONFIG_FILES.
  • Вместо того, чтобы начинать с #!/usr/bin/env python, используйте #!@PYTHON@

Тогда у ваших результирующих Python-скриптов всегда будет соответствующий шебанг.

Итак, у вас есть это решение, по крайней мере, возможно, если не практично.

0 голосов
/ 04 сентября 2008

@ morais: Это интересная идея, но я думаю, что, может быть, мы сможем сделать еще один шаг вперед. Может быть, есть способ использовать virtualenv Яна Бикинга для:

  • Посмотрим, для начала ли мы работаем в приемлемой среде, и если да, то ничего не делаем.
  • Проверьте, существует ли исполняемый файл для конкретной версии на PATH, т.е. проверьте, существует ли python2.x for x in reverse(range(4, 10)). Если это так, повторите команду с лучшим интерпретатором.
  • Если лучшего интерпретатора не существует, используйте virtualenv, чтобы попытаться установить более новую версию Python из более старой версии Python и получить все необходимые пакеты.

Я понятия не имею, способен ли virtualenv на это, поэтому я скоро начну с ним возиться. :)

...