我有这个问题:
System A
运行Ubuntu并需要Python 2.6
来处理一系列不同的事情
我在Python 2.7
上单独安装了System A
System B
原生Python 2.7
。
我有一个python脚本BLAH
,上面写着#!/bin/env python
。
再向下,它会执行另一个脚本SIGH
,最后也会说:#!/bin/env python
。
BLAH
需要在System A
或System B
上运行,并且始终需要运行Python 2.7
----
到目前为止我的解决方案的一部分:
有一个包装器脚本,首先尝试查看which python
是否指向Python 2.7
如果没关系,那么使用python的路径运行BLAH
否则尝试which python2.7
并使用该路径运行BLAH
,并将该路径添加到env PATH
。
此解决方案的问题是:
On System A
(已单独安装Python 2.7)
当BLAH
执行时,它会运行Python 2.7,因为我写的包装脚本(好吧到目前为止......)
当BLAH
生成SIGH
时,SIGH
使用shebang在路径中查找python,然后遇到麻烦,因为它在env
的{{1}}中寻找python它应该在路径中寻找PATH
。
有没有一种处理这个问题的干净方法?
提前致谢!
答案 0 :(得分:11)
如果您的脚本需要某个python版本,例如2.7,我会将第一行更改为
#!/bin/env python2.7
然后确保python2.7
在您的路径上(您可能必须根据需要添加符号链接)。在我使用的所有发行版中,这些符号链接已经存在。
(事实上,python
通常是pythonX
的符号链接,它是pythonX.Y
的符号链接,在我的情况下是python -> python2 -> python2.7
的符号链接。)
没有必要对完整路径进行硬编码,因为这可能因发行版到发行版或盒子而异。
但是,由于名为python2.7
的路径上的可执行文件不应该存在歧义,因此您应该没有问题硬编码路径。
或者,在第一个脚本中,您可以直接调用python解释器,如:
subprocess.Popen(['pythonX.Y', SCRIPT_NAME])
而不是
subprocess.Popen([SCRIPT_NAME])
编辑正如J.F. Sebastian在评论中指出的那样,您可以在第一个参数中使用sys.executable来确保第二个脚本与第一个脚本一起传递给同一个解释器。 e.g
subprocess.Popen([sys.executable, SCRIPT_NAME])
作为附注,可能有用也可能没用,您可以通过
访问脚本中“当前”Python解释器的版本import sys
print(sys.hexversion)
可能有助于确定正确的解释器是否正在运行。
答案 1 :(得分:3)
我要做的是先将#!/bin/env
直接更改为python2.7
路径,例如:#!/usr/local/bin/python2.7
即可。
如果系统A和B的python2.7路径位于不同的地方(这似乎是你的情况),你可以随时创建一个符号链接:
ln -s /bin/python2.7 /usr/local/bin/python2.7
它应该可以正常工作。
答案 2 :(得分:2)
为什么不使用virtualenv?它允许你使用任何安装的python版本(除了其他东西)......
starenka /tmp % virtualenv test -ppython2.6
Running virtualenv with interpreter /usr/bin/python2.6
New python executable in test/bin/python2.6
Also creating executable in test/bin/python
Installing setuptools............................done.
Installing pip...............done.
starenka /tmp % source test/bin/activate
(test)starenka /tmp % which python
/tmp/test/bin/python
(test)starenka /tmp % python --version
Python 2.6.8
(test)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test/test.py
(test)starenka /tmp % chmod +x test/test.py
(test)starenka /tmp % test/test.py
(2, 6, 8, 'final', 0)
starenka /tmp % virtualenv test7 -ppython2.7
Running virtualenv with interpreter /usr/bin/python2.7
New python executable in test7/bin/python2.7
Also creating executable in test7/bin/python
Installing setuptools............done.
Installing pip...............done.
starenka /tmp % source test7/bin/activate
(test7)starenka /tmp % which python
/tmp/test7/bin/python
(test7)starenka /tmp % python --version
Python 2.7.3rc2
(test7)starenka /tmp % echo '#!/usr/bin/env python\nimport sys; print sys.version_info' > test7/test.py
(test7)starenka /tmp % chmod +x test7/test.py
(test7)starenka /tmp % test7/test.py
sys.version_info(major=2, minor=7, micro=3, releaselevel='candidate', serial=2)
答案 3 :(得分:0)
愚蠢而简单
在shell中,如果需要:
ln -s /path/to/your/python2.X /usr/local/bin/python2
在Python脚本中:
#!/bin/bash
"exec" "python2" "$0"
我遇到过这种问题,这个解决方案解决了大多数情况,并且可以轻松地从一个系统移植到另一个系统(您可能面临系统之间的不同路径,不同版本的软件...... )。首先创建一个符号链接,以确保您将运行正确版本的Python(特别是现在,如果Python3只是Python,你现在就不会这样),然后依赖于bash环境。因此,每次定位系统时,都不会更改脚本,因为它不会调用包的麻烦。