Подтвердить что ты не робот

Развертывание Python и/usr/bin/env

В начале всех исполняемых скриптов 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). Может быть, какая-то утилита распределения требуется для предотвращения ручных настроек?

4b9b3361

Ответ 1

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

Ответ 2

Довольно хакерское решение - если ваш чек не работает, используйте эту функцию (которая, вероятно, может быть значительно улучшена), чтобы определить лучший доступный интерпретатор, определить, приемлемо ли это, и если так перезапустить ваш script с 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]

Ответ 3

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

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

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

В качестве альтернативы запустите свой python script с помощью явного интерпретатора, который вы хотите:

$ /path/to/python2.4 <your script>

Ответ 4

@morais: Это интересная идея, но я думаю, возможно, мы сможем сделать это на шаг дальше. Возможно, есть способ использовать Ian Bicking virtualenv для:

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

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

Ответ 5

Здесь решение, если вы (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, используйте #[email protected]@

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

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