【问题标题】:Python deployment and /usr/bin/env portabilityPython 部署和 /usr/bin/env 可移植性
【发布时间】:2008-09-02 21:21:14
【问题描述】:

在我所有可执行的 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 具有~/bin在 Python 2.2 路径之前)。也许需要一些分发实用程序来防止手动调整?

【问题讨论】:

    标签: python executable environment shebang


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      相当骇人听闻的解决方案 - 如果您的检查失败,请使用此功能(可能会显着改进)来确定可用的最佳解释器,确定它是否可以接受,如果可以,请使用 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 列表一起使用。
      【解决方案3】:

      如果您正在运行脚本,那么您可以先将 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>
      

      【讨论】:

        【解决方案4】:

        @morais:这是一个有趣的想法,但我认为也许我们可以更进一步。也许有一种方法可以使用Ian Bicking's 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 二进制文件。方法是here

        所以,你的流程是:

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

        那么您的 resultant Python 脚本将始终具有适当的 shebang。

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

        【讨论】:

          猜你喜欢
          • 2011-09-23
          • 1970-01-01
          • 2013-07-16
          • 1970-01-01
          • 1970-01-01
          • 2016-11-23
          • 2016-03-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多