Python部署和/ usr / bin / env可移植性

时间:2008-09-02 21:21:14

标签: python executable environment shebang

在我所有可执行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。

优雅的解决方案是什么?

[编辑:]我没有具体提出这个问题 - 我想让用户在没有手动配置的情况下执行脚本(例如~/bin中的路径更改或符号链接,并确保您的PATH {在Python 2.2路径之前的{1}}。也许需要一些分发工具来阻止手动调整?

5 个答案:

答案 0 :(得分:8)

“env”只是执行它在PATH env var中找到的第一件事。要切换到不同的python,请在调用脚本之前将该python可执行文件的目录添加到路径中。

答案 1 :(得分:4)

非常糟糕的解决方案 - 如果您的检查失败,请使用此功能(可能会有显着改进)来确定可用的最佳解释器,确定它是否可接受,如果是这样,则使用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 :(得分:2)

如果您正在运行脚本,那么您可以先将PATH变量设置为指向私有bin目录:

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

然后当你执行你的python脚本时,它将使用python 2.4。您必须更改登录脚本才能更改PATH。

或者使用您想要的显式解释器运行您的python脚本:

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

答案 3 :(得分:0)

@morais:这是一个有趣的想法,但我想也许我们可以更进一步。也许有办法使用Ian Bicking's virtualenv来:

  • 看看我们是否在可接受的环境中运行,如果是,则不执行任何操作。
  • 检查PATH上是否存在特定于版本的可执行文件,即检查python2.x是否存在for x in reverse(range(4, 10))。如果是这样,请使用更好的解释器重新运行该命令。
  • 如果不存在更好的解释器,请使用virtualenv尝试从旧版本的Python安装更新版本的Python并获取任何必备软件包。

我不知道virtualenv能否做到这一点,所以我很快就会搞砸它。 :)

答案 4 :(得分:0)

如果您(1)完全使用shebangs并且(2)能够在构建过程中使用Autotools,那么这是一个解决方案。

我昨晚发现你可以使用autoconf宏AM_PATH_PYTHON找到一个最小的Python 2 二进制文件。方法是here

所以,你的过程将是:

  • AM_PATH_PYTHON(2.4)
  • 中发出configure.ac
  • 将所有.py脚本重命名为.py.in(根据我的经验,这并不会混淆vi
  • 使用AC_CONFIG_FILES命名要生成的所有Python脚本。
  • 使用#!/usr/bin/env python
  • ,而不是从#!@PYTHON@开始

然后您的结果 Python脚本将始终具有适当的shebang。

所以,你有这个解决方案,至少可能,如果不实用的话。