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

13
在我所有可执行的Python脚本开头,我都会加上shebang行:
#!/usr/bin/env python

我在一个env python返回Python 2.2环境的系统上运行这些脚本。我的脚本很快会失败,因为我手动检查了兼容的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路径之前包含~/bin)的情况下执行脚本。也许需要某种分发实用工具来防止手动调整?

5个回答

8
"

“env”只是在PATH环境变量中查找并执行第一个匹配的程序。若要切换到不同版本的Python,请在调用脚本之前将该Python可执行文件所在的目录添加到PATH中。

"

4
比较hack的解决方案 - 如果您的检查失败了,可以使用这个函数(可能需要显著改进)来确定可用的最佳解释器,确定是否可接受,如果是,使用新解释器通过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]

此外,建议他使用 os.exec 函数来执行找到的可执行文件和 sys.argv 列表。 - tzot

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>

0

如果你(1)绝对要使用shebangs并且(2)能够在构建过程中使用Autotools,那么这里有一个解决方案。

我昨晚刚发现,你可以使用autoconf宏AM_PATH_PYTHON来查找最小的Python2二进制文件。具体方法请参见此处

因此,您的处理过程如下:

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

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

因此,您至少有这个解决方案,即使不实用也是可能的。


0

@morais: 这是一个有趣的想法,但我认为我们可以更进一步。也许有一种方法可以使用Ian Bicking's virtualenv来实现以下目标:

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

我不知道virtualenv是否能够实现这一点,所以我会很快去尝试一下。 :)


如果你使用的是Windows操作系统,你所描述的一些逻辑可以从PEP 397 Python launcher for Windows中获取。 - Piotr Dobrogost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接