shebang env首选python版本
我有一些python-2.x脚本,我在不同的系统,Debian和Arch linux之间复制。 Debian将python安装为'/ usr / bin / python',而Arch将其安装为'/ usr / bin / python2'。 一个问题是在Arch linux的'/ usr / bin / python'中也存在引用python-3.x的东西。 所以每次我复制一个文件时,我必须纠正shebang行,这有点烦人。
在我使用的拱门上
#!/usr/bin/env python2
而在debian上我有
#!/usr/bin/env python
由于'python2'在Debian上不存在,有没有办法通过首选应用程序? 也许有一些shell扩展? 我不介意它是否取决于现有的'/ bin / sh'。 以下将是很好,但不工作。
#!/usr/bin/env python2 python
#!/usr/bin/env python{2,}
#!/bin/sh python{2,}
#!/bin/sh -c python{2,}
令人沮丧的是`sh -c python {2,}'在命令行上工作:即它在可用时调用python2,否则调用python。
我宁愿不在Debian上建立一个'python2-> python'链接,因为如果我把脚本给别人,它不会运行。 我也不想在Arch上将python2指向python2,因为它会与更新断开。
有没有一个干净的方式来做到这一点,而不写封装?
我意识到之前已经问过类似的问题,但是我没有看到任何符合我的边界条件的答案:)针对不同版本的Python的条件shebang行
---更新
我一起砍了一个丑陋的shell解决方案,现在可以完成这项工作。
#!/bin/bash
pfound=false; v0=2; v1=6
for p in /{usr/,}bin/python*; do
v=($(python -V 2>&1 | cut -c 7- | sed 's/./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
done
if ! $pfound; then echo "no suitable python version (2.6.x) found."; exit 1; fi
$p - $* <<EOF
PYTHON SCRIPT GOES HERE
EOF
解释:获取版本号(v是一个bash数组)并检查
v=($(python -V 2>&1 | cut -c 7- | sed 's/./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
从stdin( - )的输入启动找到的程序$ p并传递参数($ *)
$p - $* <<EOF
...
EOF
#!/bin/sh
''''which python2 >/dev/null 2>&1 && exec python2 "$0" "$@" # '''
''''which python >/dev/null 2>&1 && exec python "$0" "$@" # '''
''''exec echo "Error: I can't find python anywhere" # '''
import sys
print sys.argv
这首先作为shell脚本运行。 你可以把几乎所有的shell代码之间''''
和# '''
。 这样的代码将由shell执行。 然后,当python在文件上运行时,python会忽略这些行,因为它们看起来像Python的三重引号字符串。
shell脚本测试二进制文件是否存在于which python2 >/dev/null
的路径中,然后执行它(如果有的话)(所有参数都放在正确的位置)。 有关这方面的更多信息,请参阅为什么此代码段在4个单引号内使用shebang#!/ bin / sh和exec python工作?
注意:该行以四个'
开始,并且它们之间必须没有空格'
和shell命令的开始之间( which
...)
像这样的东西:
#!/usr/bin/env python
import sys
import os
if sys.version_info >= (3, 0):
os.execvp("python2.7", ["python2.7", __file__])
os.execvp("python2.6", ["python2.6", __file__])
os.execvp("python2", ["python2", __file__])
print ("No sutable version of Python found")
exit(2)
更新下面是相同的更强大的版本。
#!/bin/bash
ok=bad
for pyth in python python2.7 python2.6 python2; do
pypath=$(type -P $pyth)
if [[ -x $pypath ]] ; then
ok=$(
$pyth <<@@
import sys
if sys.version_info < (3, 0):
print ("ok")
else:
print("bad")
@@
)
if [[ $ok == ok ]] ; then
break
fi
fi
done
if [[ $ok != ok ]]; then
echo "Could not find suitable python version"
exit 2
fi
$pyth <<@@
<<< your python script goes here >>>
@@
我将留在这里供将来参考。
我所有的脚本通常都是为Python 3编写的,所以我使用Aaron McDaid的答案的修改版来检查Python 3而不是2:
#!/usr/bin/env sh
''''which python3 >/dev/null 2>&1 && exec python3 "$0" "$@" # '''
''''test $(python --version 2>&1 | cut -c 8) -eq 3 && exec python "$0" "$@" # '''
''''exec echo "Python 3 not found." # '''
import sys
print sys.argv
链接地址: http://www.djcxy.com/p/46413.html
上一篇: shebang env preferred python version
下一篇: #!/usr/bin/python and #!/usr/bin/env python, which support?