i have thousands of servers(linux), some only has python 2.x and some only has python 3.x, i want to write one script check.py can run on all servers just as $./check.py without use $python check.py or $python3 check.py, is there any way to do this?
我有成千上万的服务器(linux),有些只有python 2.x而有些只有python 3.x,我想写一个脚本check.py可以在所有服务器上运行,就像$。/ check.py而不使用$ python check.py或$ python3 check.py,有没有办法做到这一点?
my question is how the script check.py find the Interpreter no matter the Interpreter is python2.x and python3.x
我的问题是脚本check.py如何找到解释器,无论解释器是python2.x和python3.x
2 个解决方案
#1
13
Many scripts can run on both 2.x and 3.x. (I've got a bunch I work on on a daily basis, and I've converted various open source libraries from 2.x-only to dual-version.)
许多脚本可以在2.x和3.x上运行。 (我每天都有一堆工作,并且我已经将各种开源库从2.x-only转换为双版本。)
A few things make it much easier:
一些事情使它变得容易:
- Require 2.7, or at least 2.6+, for 2.x users. Otherwise, for example, you cannot raise and exceptions with parameters or catch them into variables, and other such severe limitations.
- Require 3.3+, or at least 3.2+, for 3.x users. Most of the gratuitous incompatibilities (like the
u
prefix being taken away) were reversed in 3.2 or 3.3. - Use the six library.
- Use
__future__
statements. - Always be clear in your head about whether you mean
bytes
(always 8-bit),unicode
(must encode if you want 8-bit), orstr
(whatever most of the stdlib APIs expect), andencode
anddecode
as necessary. - Regularly run
2to3
on your code. (But don't blindly do everything it says. If, e.g., you're usingd.keys()
ormap(f, l)
because you don't care whether you get back alist
or not, you'll get a warning, because2to3
doesn't know you don't care.)
2.x用户需要2.7或至少2.6+。否则,例如,您不能使用参数引发和异常或将它们捕获到变量中,以及其他此类严重限制。
3.x用户需要3.3+或至少3.2+。大多数无偿的不兼容性(如u前缀被带走)在3.2或3.3中被颠倒过来。
使用六个库。
使用__future__语句。
始终清楚你的意思是你的意思是字节(总是8位),unicode(必须编码,如果你想要8位),或str(无论大多数stdlib API期望),并根据需要进行编码和解码。
定期在代码上运行2to3。 (但不要盲目地做它所说的一切。例如,如果你使用d.keys()或map(f,l),因为你不关心你是否回到列表,你会得到一个警告,因为2to3不知道你不在乎。)
Alternatively, instead of trying to write code that runs on both, write code that runs on 2.x, but can be automatically transformed by 2to3
into running 3.x code, and make that part of your installation process (in setup.py
, if sys.version_info >= (3, 0):
do the 2to3
step).
或者,不要尝试编写在两者上运行的代码,而是编写在2.x上运行的代码,但可以通过2to3自动转换为运行3.x代码,并在安装过程中进行安装(在setup.py中, if sys.version_info> =(3,0):执行2to3步骤)。
From your edit, it sounds like you're mostly concerned with what to put in the #! line. For that:
从您的编辑中,听起来您最关心的是放入#!线。为了那个原因:
/usr/bin/env python
This isn't guaranteed to work—but then env
isn't guaranteed to work in the first-place… You can count on the fact that:
这不能保证工作 - 但是env不能保证在第一位工作......你可以指望这样的事实:
- On just about any system where the platform/distro supplies only 2.x,
python
is Python 2. - On just about any system where the platform/distro supplies both,
python
is Python 2. - On just about any system where the platform/distro supplies only 3.x (which currently is very rare, but will presumably eventually be more common),
python
is Python 3.
在几乎任何平台/发行版仅提供2.x的系统上,python是Python 2。
几乎所有平台/发行版都提供的系统,python都是Python 2。
几乎所有平台/发行版仅提供3.x的系统(目前非常罕见,但最终可能会更常见),python是Python 3。
However:
- On a system where the platform supplies neither, if the admin only installed 3.x, it will likely (as of early 2013) not be available as
python
. There's not much you can do about this one.
在平台不提供的系统上,如果管理员只安装了3.x,则很可能(截至2013年初)不能用作python。关于这一点,你无能为力。
If the last one is a serious problem, you can work around it by adding a launcher script, written in sh, that tries python
and then tries python3
if that fails.
如果最后一个是一个严重的问题,你可以通过添加一个用sh编写的启动器脚本来尝试python,然后尝试python3(如果失败)。
The nice way to do this is to specify the launcher script itself as the shebang interpreter in your Python script. Linux can handle this, but it's configurable, and at least some distros disable it by default—and most other *nix systems can't do it.
执行此操作的好方法是将启动器脚本本身指定为Python脚本中的shebang解释器。 Linux可以处理这个,但它是可配置的,并且至少有一些发行版默认禁用它 - 而且大多数其他* nix系统都无法做到这一点。
If that doesn't work, the next best option is to make the user run the launcher script—that is, tell them to do ./check.sh
instead of ./check.py
, and check.sh
figures out the right Python interpreter and runs $python ./check.py
for the user.
如果这不起作用,下一个最好的选择是让用户运行启动器脚本 - 也就是说,告诉他们执行./check.sh而不是./check.py,并且check.sh找出正确的Python解释器并为用户运行$ python ./check.py。
If you want to get really tricky, you could even embed the Python script as a heredoc inside the shell script, so you only need to distribute one file. They run ./check.sh
, and it finds the right Python and runs it on the heredoc.
如果你想变得非常棘手,你甚至可以将Python脚本作为heredoc嵌入shell脚本中,因此你只需要分发一个文件。它们运行./check.sh,它找到了正确的Python并在heredoc上运行它。
#2
0
Considering that Python 3.x is not entirely backwards compatible with Python 2.x, you would have to ensure that the script was compatible with both versions. This can be done with some help from the 2to3
tool, but may ultimately mean running two distinct Python scripts.
考虑到Python 3.x并不完全向后兼容Python 2.x,您必须确保脚本与这两个版本兼容。这可以通过2to3工具的一些帮助来完成,但最终可能意味着运行两个不同的Python脚本。
#1
13
Many scripts can run on both 2.x and 3.x. (I've got a bunch I work on on a daily basis, and I've converted various open source libraries from 2.x-only to dual-version.)
许多脚本可以在2.x和3.x上运行。 (我每天都有一堆工作,并且我已经将各种开源库从2.x-only转换为双版本。)
A few things make it much easier:
一些事情使它变得容易:
- Require 2.7, or at least 2.6+, for 2.x users. Otherwise, for example, you cannot raise and exceptions with parameters or catch them into variables, and other such severe limitations.
- Require 3.3+, or at least 3.2+, for 3.x users. Most of the gratuitous incompatibilities (like the
u
prefix being taken away) were reversed in 3.2 or 3.3. - Use the six library.
- Use
__future__
statements. - Always be clear in your head about whether you mean
bytes
(always 8-bit),unicode
(must encode if you want 8-bit), orstr
(whatever most of the stdlib APIs expect), andencode
anddecode
as necessary. - Regularly run
2to3
on your code. (But don't blindly do everything it says. If, e.g., you're usingd.keys()
ormap(f, l)
because you don't care whether you get back alist
or not, you'll get a warning, because2to3
doesn't know you don't care.)
2.x用户需要2.7或至少2.6+。否则,例如,您不能使用参数引发和异常或将它们捕获到变量中,以及其他此类严重限制。
3.x用户需要3.3+或至少3.2+。大多数无偿的不兼容性(如u前缀被带走)在3.2或3.3中被颠倒过来。
使用六个库。
使用__future__语句。
始终清楚你的意思是你的意思是字节(总是8位),unicode(必须编码,如果你想要8位),或str(无论大多数stdlib API期望),并根据需要进行编码和解码。
定期在代码上运行2to3。 (但不要盲目地做它所说的一切。例如,如果你使用d.keys()或map(f,l),因为你不关心你是否回到列表,你会得到一个警告,因为2to3不知道你不在乎。)
Alternatively, instead of trying to write code that runs on both, write code that runs on 2.x, but can be automatically transformed by 2to3
into running 3.x code, and make that part of your installation process (in setup.py
, if sys.version_info >= (3, 0):
do the 2to3
step).
或者,不要尝试编写在两者上运行的代码,而是编写在2.x上运行的代码,但可以通过2to3自动转换为运行3.x代码,并在安装过程中进行安装(在setup.py中, if sys.version_info> =(3,0):执行2to3步骤)。
From your edit, it sounds like you're mostly concerned with what to put in the #! line. For that:
从您的编辑中,听起来您最关心的是放入#!线。为了那个原因:
/usr/bin/env python
This isn't guaranteed to work—but then env
isn't guaranteed to work in the first-place… You can count on the fact that:
这不能保证工作 - 但是env不能保证在第一位工作......你可以指望这样的事实:
- On just about any system where the platform/distro supplies only 2.x,
python
is Python 2. - On just about any system where the platform/distro supplies both,
python
is Python 2. - On just about any system where the platform/distro supplies only 3.x (which currently is very rare, but will presumably eventually be more common),
python
is Python 3.
在几乎任何平台/发行版仅提供2.x的系统上,python是Python 2。
几乎所有平台/发行版都提供的系统,python都是Python 2。
几乎所有平台/发行版仅提供3.x的系统(目前非常罕见,但最终可能会更常见),python是Python 3。
However:
- On a system where the platform supplies neither, if the admin only installed 3.x, it will likely (as of early 2013) not be available as
python
. There's not much you can do about this one.
在平台不提供的系统上,如果管理员只安装了3.x,则很可能(截至2013年初)不能用作python。关于这一点,你无能为力。
If the last one is a serious problem, you can work around it by adding a launcher script, written in sh, that tries python
and then tries python3
if that fails.
如果最后一个是一个严重的问题,你可以通过添加一个用sh编写的启动器脚本来尝试python,然后尝试python3(如果失败)。
The nice way to do this is to specify the launcher script itself as the shebang interpreter in your Python script. Linux can handle this, but it's configurable, and at least some distros disable it by default—and most other *nix systems can't do it.
执行此操作的好方法是将启动器脚本本身指定为Python脚本中的shebang解释器。 Linux可以处理这个,但它是可配置的,并且至少有一些发行版默认禁用它 - 而且大多数其他* nix系统都无法做到这一点。
If that doesn't work, the next best option is to make the user run the launcher script—that is, tell them to do ./check.sh
instead of ./check.py
, and check.sh
figures out the right Python interpreter and runs $python ./check.py
for the user.
如果这不起作用,下一个最好的选择是让用户运行启动器脚本 - 也就是说,告诉他们执行./check.sh而不是./check.py,并且check.sh找出正确的Python解释器并为用户运行$ python ./check.py。
If you want to get really tricky, you could even embed the Python script as a heredoc inside the shell script, so you only need to distribute one file. They run ./check.sh
, and it finds the right Python and runs it on the heredoc.
如果你想变得非常棘手,你甚至可以将Python脚本作为heredoc嵌入shell脚本中,因此你只需要分发一个文件。它们运行./check.sh,它找到了正确的Python并在heredoc上运行它。
#2
0
Considering that Python 3.x is not entirely backwards compatible with Python 2.x, you would have to ensure that the script was compatible with both versions. This can be done with some help from the 2to3
tool, but may ultimately mean running two distinct Python scripts.
考虑到Python 3.x并不完全向后兼容Python 2.x,您必须确保脚本与这两个版本兼容。这可以通过2to3工具的一些帮助来完成,但最终可能意味着运行两个不同的Python脚本。