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.
什么是优雅的解决方案?
[编辑:]我在提出问题时还不够具体-我想让用户无需手动配置即可执行脚本(例如,路径更改或者〜/ bin
中的符号链接,并确保PATH具有〜/ bin
在Python 2.2路径之前)。也许需要一些分发实用程序来防止手动调整?
解决方案
回答
" env"只是执行它在PATH env var中找到的第一件事。要切换到其他python,请在调用脚本之前将该python可执行文件的目录放在路径之前。
回答
如果正在运行脚本,则可以将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>
回答
如果检查失败,这是一个非常骇人听闻的解决方案,请使用此功能(可能会得到显着改进)来确定可用的最佳解释器,确定它是否可以接受,如果可以,请使用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]
回答
@morais:这是一个有趣的想法,但我认为也许我们可以再走一步。也许有一种方法可以使用Ian Bicking的virtualenv来:
- 首先看看我们是否在可接受的环境中运行,如果是,则什么也不做。
- 检查在PATH上是否存在特定于版本的可执行文件,即检查是否存在python2.x对于反向x(范围(4,10))是存在的。如果是这样,请使用更好的解释器重新运行该命令。
- 如果没有更好的解释器,请使用virtualenv尝试从较旧的Python版本安装Python的较新版本,并获取所有必备软件包。
我不知道virtualenv是否能够做到这一点,所以我很快就会解决它。 :)