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?