当前位置:首页> 正文

关于可执行文件:Python部署和/ usr / bin / env可移植性

关于可执行文件:Python部署和/ usr / bin / env可移植性

Python deployment and /usr/bin/env portability

在所有可执行Python脚本的开头,我都添加了shebang行:

1
#!/usr/bin/env python

我正在env python产生Python 2.2环境的系统上运行这些脚本。我的脚本很快失败了,因为我需要手动检查兼容的Python版本:

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

如果可能的话,我不想更改每个可执行文件的shebang行;但是,我没有对该计算机的管理访问权限来更改env python的结果,并且我不想强制使用特定版本,例如:

1
#!/usr/bin/env python2.4

我想避免这种情况,因为系统可能具有比Python 2.4更高的版本,或者可能具有Python 2.5但没有Python 2.4。

什么是优雅的解决方案?

[编辑:]我在提出问题时还不够具体-我想让用户无需手动配置即可执行脚本(例如,路径更改或~/bin中的符号链接,并确保您的PATH具有~/bin在Python 2.2路径之前)。也许需要一些分发实用程序来防止手动调整?


" env "简单地执行它在PATH env var中找到的第一件事。要切换到其他python,请在调用脚本之前将该Python \\可执行文件的目录放在路径之前。


一个非常骇人听闻的解决方案-如果检查失败,请使用此功能(可能会大大改进)来确定可用的最佳解释器,确定它是否可以接受,如果可以,请使用os.system或类似的方法重新启动您的脚本您的sys.argv使用新的解释器。

1
2
3
4
5
6
7
8
9
10
11
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]

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

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

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

或者使用所需的显式解释器运行python脚本:

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

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

我昨晚才发现,您可以使用autoconf宏AM_PATH_PYTHON查找最小的Python 2二进制文件。操作方法在这里。

因此,您的过程将是:

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

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

因此,如果不切实际,至少有此解决方案。


@morais:这是一个有趣的想法,但我认为也许我们可以再走一步。也许有一种方法可以使用Ian Bicking的virtualenv进行以下操作:

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

我不知道virtualenv是否能够做到这一点,所以我很快就会解决它。 :)


展开全文阅读

相关内容