6

我有数千台服务器(linux),有些只有 python 2.x,有些只有 python 3.x,我想写一个脚本 check.py 可以在所有服务器上运行,就像 $./check.py 不使用 $ python check.py 或 $python3 check.py,有没有办法做到这一点?

我的问题是脚本 check.py 如何找到解释器,无论解释器是 python2.x 和 python3.x

4

3 回答 3

14

许多脚本可以在 2.x 和 3.x 上运行。(我每天都有很多工作,我已经将各种开源库从仅 2.x 转换为双版本。)

有几件事使它变得容易得多:

  • 对于 2.x 用户,需要 2.7,或至少 2.6+。否则,例如,您不能使用参数引发异常或将它们捕获到变量中,以及其他此类严重限制。
  • 对于 3.x 用户,需要 3.3+,或至少 3.2+。在 3.2 或 3.3 中,大多数无缘无故的不兼容(如u前缀被删除)都被逆转了。
  • 使用库。
  • 使用__future__语句。
  • 始终清楚您的意思是bytes(始终为 8 位)、unicode(如果您想要 8 位则必须编码)或str(大多数 stdlib API 所期望的),以及encode必要decode时。
  • 定期2to3在您的代码上运行。(但不要盲目地做它所说的一切。例如,如果您正在使用d.keys()或者map(f, l)因为您不在乎是否返回 a list,您会收到警告,因为2to3不知道您不知道关心。)

或者,不要尝试编写在两者上运行的代码,而是编写在 2.x 上运行但可以自动转换2to3为运行 3.x 代码的代码,并将该部分作为安装过程的一部分(在 中setup.pyif sys.version_info >= (3, 0):执行2to3步骤) .

从您的编辑来看,听起来您最关心的是在 #! 中放入什么!线。为了那个原因:

/usr/bin/env python

这不能保证有效,但env不能保证一开始就有效……您可以依靠以下事实:

  • 在平台/发行版仅提供 2.x 的任何系统上,python都是 Python 2。
  • 在平台/发行版同时提供两者的任何系统上,python都是 Python 2。
  • 在平台/发行版仅提供 3.x(目前非常罕见,但可能最终会更常见)的任何系统上,python都是 Python 3。

然而:

  • 平台既不提供. _ 你对此无能为力。python

如果最后一个是一个严重的问题,您可以通过添加一个用 sh 编写的启动器脚本来解决它,该脚本会尝试pythonpython3在失败时尝试。

这样做的好方法是将启动器脚本本身指定为 Python 脚本中的 shebang 解释器。Linux 可以处理这个问题,但它是可配置的,并且至少一些发行版默认禁用它——而大多数其他 *nix 系统无法做到这一点。

如果这不起作用,下一个最佳选择是让用户运行启动器脚本——也就是说,告诉他们这样做./check.sh而不是./check.py,并check.sh找出正确的 Python 解释器并$python ./check.py为用户运行。

如果你想变得非常棘手,你甚至可以将 Python 脚本作为一个 heredoc 嵌入到 shell 脚本中,这样你只需要分发一个文件。他们运行./check.sh,它会找到正确的 Python 并在 heredoc 上运行它。

于 2013-01-04T07:02:21.810 回答
0

考虑到 Python 3.x 并不完全向后兼容 Python 2.x,您必须确保该脚本与这两个版本兼容。这可以在2to3工具的帮助下完成,但最终可能意味着运行两个不同的 Python 脚本。

于 2013-01-04T07:00:09.110 回答
0

在一般情况下,没有;许多 Python 2 脚本无法在 Python 3 上运行,反之亦然。它们是两种不同的语言。

话虽如此,如果你小心的话,你可以编写一个在两者下都能正常运行的脚本。一些作者特别注意确保他们的脚本在两个版本之间兼容,通常使用额外的工具,如six库(这个名字是双关语;你可以通过将“二乘以三”或“三乘以二”来达到“六” ”)。

然而,现在是 2020 年,Python 2 正式死亡。许多以前在 Python 2 仍受支持的情况下努力维护它的兼容性的维护者现在会如释重负,并且通常非常乐意在未来继续使用它。

于 2020-10-01T08:13:47.603 回答