我有数千台服务器(linux),有些只有 python 2.x,有些只有 python 3.x,我想写一个脚本 check.py 可以在所有服务器上运行,就像 $./check.py 不使用 $ python check.py 或 $python3 check.py,有没有办法做到这一点?
我的问题是脚本 check.py 如何找到解释器,无论解释器是 python2.x 和 python3.x
我有数千台服务器(linux),有些只有 python 2.x,有些只有 python 3.x,我想写一个脚本 check.py 可以在所有服务器上运行,就像 $./check.py 不使用 $ python check.py 或 $python3 check.py,有没有办法做到这一点?
我的问题是脚本 check.py 如何找到解释器,无论解释器是 python2.x 和 python3.x
许多脚本可以在 2.x 和 3.x 上运行。(我每天都有很多工作,我已经将各种开源库从仅 2.x 转换为双版本。)
有几件事使它变得容易得多:
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.py
,if sys.version_info >= (3, 0):
执行2to3
步骤) .
从您的编辑来看,听起来您最关心的是在 #! 中放入什么!线。为了那个原因:
/usr/bin/env python
这不能保证有效,但env
不能保证一开始就有效……您可以依靠以下事实:
python
都是 Python 2。python
都是 Python 2。python
都是 Python 3。然而:
python
如果最后一个是一个严重的问题,您可以通过添加一个用 sh 编写的启动器脚本来解决它,该脚本会尝试python
并python3
在失败时尝试。
这样做的好方法是将启动器脚本本身指定为 Python 脚本中的 shebang 解释器。Linux 可以处理这个问题,但它是可配置的,并且至少一些发行版默认禁用它——而大多数其他 *nix 系统无法做到这一点。
如果这不起作用,下一个最佳选择是让用户运行启动器脚本——也就是说,告诉他们这样做./check.sh
而不是./check.py
,并check.sh
找出正确的 Python 解释器并$python ./check.py
为用户运行。
如果你想变得非常棘手,你甚至可以将 Python 脚本作为一个 heredoc 嵌入到 shell 脚本中,这样你只需要分发一个文件。他们运行./check.sh
,它会找到正确的 Python 并在 heredoc 上运行它。
考虑到 Python 3.x 并不完全向后兼容 Python 2.x,您必须确保该脚本与这两个版本兼容。这可以在2to3
工具的帮助下完成,但最终可能意味着运行两个不同的 Python 脚本。
在一般情况下,没有;许多 Python 2 脚本无法在 Python 3 上运行,反之亦然。它们是两种不同的语言。
话虽如此,如果你小心的话,你可以编写一个在两者下都能正常运行的脚本。一些作者特别注意确保他们的脚本在两个版本之间兼容,通常使用额外的工具,如six
库(这个名字是双关语;你可以通过将“二乘以三”或“三乘以二”来达到“六” ”)。
然而,现在是 2020 年,Python 2 正式死亡。许多以前在 Python 2 仍受支持的情况下努力维护它的兼容性的维护者现在会如释重负,并且通常非常乐意在未来继续使用它。