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

时间:2021-03-21 23:24:12

At the beginning of all my executable Python scripts I put the shebang line:

在我所有的可执行Python脚本的开头,我把shebang行:

#!/usr/bin/env python

I'm running these scripts on a system where env python yields a Python 2.2 environment. My scripts quickly fail because I have a manual check for a compatible Python version:

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

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

I don't want to have to change the shebang line on every executable file, if it's possible; however, I don't have administrative access to the machine to change the result of env python and I don't want to force a particular version, as in:

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

#!/usr/bin/env python2.4

I'd like to avoid this because system may have a newer version than Python 2.4, or may have Python 2.5 but no Python 2.4.

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

What's the elegant solution?

什么是优雅的解决方案?

[Edit:] I wasn't specific enough in posing the question -- I'd like to let users execute the scripts without manual configuration (e.g. path alteration or symlinking in ~/bin and ensuring your PATH has ~/bin before the Python 2.2 path). Maybe some distribution utility is required to prevent the manual tweaks?

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

5 个解决方案

#1


8  

"env" simply executes the first thing it finds in the PATH env var. To switch to different python, prepend the directory for that python's executable to the path before invoking your script.

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

#2


4  

Pretty hackish solution - if your check fails, use this function (which probably could be significantly improved) to determine the best interpreter available, determine if it is acceptable, and if so relaunch your script with os.system or something similar and your sys.argv using the new interpreter.

非常糟糕的解决方案 - 如果您的检查失败,请使用此功能(可能会有显着改进)来确定可用的最佳解释器,确定它是否可接受,如果是这样,则使用os.system或类似的系统重新启动脚本。 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]

#3


2  

If you are running the scripts then you can set your PATH variable to point to a private bin directory first:

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

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

Then when you execute your python script it'll use python 2.4. You'll have to change your login scripts to change your PATH.

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

Alternatively run your python script with the explicit interpreter you want:

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

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

#4


0  

@morais: That's an interesting idea, but I think maybe we can take it one step farther. Maybe there's a way to use Ian Bicking's virtualenv to:

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

  • See if we're running in an acceptable environment to begin with, and if so, do nothing.
  • 看看我们是否在可接受的环境中运行,如果是,则不执行任何操作。

  • Check if there exists a version-specific executable on the PATH, i.e. check if python2.x exists for x in reverse(range(4, 10)). If so, re-run the command with the better interpreter.
  • 检查PATH上是否存在特定于版本的可执行文件,即检查python2.x是否存在反向x(范围(4,10))。如果是这样,请使用更好的解释器重新运行该命令。

  • If no better interpreter exists, use virtualenv to try and install a newer version of Python from the older version of Python and get any prerequisite packages.
  • 如果不存在更好的解释器,请使用virtualenv尝试从旧版本的Python安装更新版本的Python并获取任何必备软件包。

I have no idea if virtualenv is capable of this, so I'll go mess around with it sometime soon. :)

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

#5


0  

Here's a solution if you're (1) absolutely set on using shebangs and (2) able to use Autotools in your build process.

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

I just found last night that you can use the autoconf macro AM_PATH_PYTHON to find a minimal Python 2 binary. The how-to is here.

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

So, your process would be:

那么,您的流程将是:

  • Issue an AM_PATH_PYTHON(2.4) in your configure.ac
  • 在configure.ac中发出AM_PATH_PYTHON(2.4)

  • Rename all of your .py scripts to .py.in (in my experience, this doesn't confuse vi)
  • 将所有.py脚本重命名为.py.in(根据我的经验,这不会混淆vi)

  • Name all of those Python scripts you want to generate with AC_CONFIG_FILES.
  • 使用AC_CONFIG_FILES命名要生成的所有Python脚本。

  • Instead of starting with #!/usr/bin/env python, use #!@PYTHON@
  • 而不是从#!/ usr / bin / env python开始,使用#!@ PYTHON @

Then your resultant Python scripts will always have an appropriate shebang.

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

So, you have this solution, at least possible, if not practical.

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

#1


8  

"env" simply executes the first thing it finds in the PATH env var. To switch to different python, prepend the directory for that python's executable to the path before invoking your script.

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

#2


4  

Pretty hackish solution - if your check fails, use this function (which probably could be significantly improved) to determine the best interpreter available, determine if it is acceptable, and if so relaunch your script with os.system or something similar and your sys.argv using the new interpreter.

非常糟糕的解决方案 - 如果您的检查失败,请使用此功能(可能会有显着改进)来确定可用的最佳解释器,确定它是否可接受,如果是这样,则使用os.system或类似的系统重新启动脚本。 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]

#3


2  

If you are running the scripts then you can set your PATH variable to point to a private bin directory first:

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

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

Then when you execute your python script it'll use python 2.4. You'll have to change your login scripts to change your PATH.

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

Alternatively run your python script with the explicit interpreter you want:

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

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

#4


0  

@morais: That's an interesting idea, but I think maybe we can take it one step farther. Maybe there's a way to use Ian Bicking's virtualenv to:

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

  • See if we're running in an acceptable environment to begin with, and if so, do nothing.
  • 看看我们是否在可接受的环境中运行,如果是,则不执行任何操作。

  • Check if there exists a version-specific executable on the PATH, i.e. check if python2.x exists for x in reverse(range(4, 10)). If so, re-run the command with the better interpreter.
  • 检查PATH上是否存在特定于版本的可执行文件,即检查python2.x是否存在反向x(范围(4,10))。如果是这样,请使用更好的解释器重新运行该命令。

  • If no better interpreter exists, use virtualenv to try and install a newer version of Python from the older version of Python and get any prerequisite packages.
  • 如果不存在更好的解释器,请使用virtualenv尝试从旧版本的Python安装更新版本的Python并获取任何必备软件包。

I have no idea if virtualenv is capable of this, so I'll go mess around with it sometime soon. :)

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

#5


0  

Here's a solution if you're (1) absolutely set on using shebangs and (2) able to use Autotools in your build process.

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

I just found last night that you can use the autoconf macro AM_PATH_PYTHON to find a minimal Python 2 binary. The how-to is here.

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

So, your process would be:

那么,您的流程将是:

  • Issue an AM_PATH_PYTHON(2.4) in your configure.ac
  • 在configure.ac中发出AM_PATH_PYTHON(2.4)

  • Rename all of your .py scripts to .py.in (in my experience, this doesn't confuse vi)
  • 将所有.py脚本重命名为.py.in(根据我的经验,这不会混淆vi)

  • Name all of those Python scripts you want to generate with AC_CONFIG_FILES.
  • 使用AC_CONFIG_FILES命名要生成的所有Python脚本。

  • Instead of starting with #!/usr/bin/env python, use #!@PYTHON@
  • 而不是从#!/ usr / bin / env python开始,使用#!@ PYTHON @

Then your resultant Python scripts will always have an appropriate shebang.

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

So, you have this solution, at least possible, if not practical.

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