shebang env首选python版本

jaa*_*aap 13 python linux scripting shebang

我有一些python-2.x脚本,我在不同的系统,Debian和Arch linux之间复制.Debian将python安装为'/ usr/bin/python',而Arch将其安装为'/ usr/bin/python2'.一个问题是,在Arch linux上,'/ usr/bin/python'也存在,它引用了python-3.x. 所以每次我复制一个文件我都要纠正shebang线,这有点烦人.

在Arch我用

#!/usr/bin/env python2
Run Code Online (Sandbox Code Playgroud)

我在debian上

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

由于Debian上不存在'python2',有没有办法传递首选应用程序?也许有一些shell扩展?我不介意它是否依赖于例如'/ bin/sh'.以下会很好,但不起作用.

#!/usr/bin/env python2 python
#!/usr/bin/env python{2,}
#!/bin/sh python{2,}
#!/bin/sh -c python{2,}
Run Code Online (Sandbox Code Playgroud)

令人沮丧的是'sh -c python {2,}'在命令行上运行:即它调用python2可用,否则调用python.

我宁愿不在Debian上创建链接'python2-> python',因为如果我将脚本提供给其他人则不会运行.我也不想让'python'指向Arch上的python2,因为它打破了更新.

没有编写包装器,有没有一种干净的方法可以做到这一点?

我之前已经意识到类似的问题,但我没有看到任何符合我的边界条件的答案:) 有条件的shebang行为不同版本的Python

---更新

我一起破解了一个丑陋的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
Run Code Online (Sandbox Code Playgroud)

解释:获取版本号(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
Run Code Online (Sandbox Code Playgroud)

使用stdin( - )输入并传递参数($*)启动找到的程序$ p

$p - $* <<EOF
...
EOF
Run Code Online (Sandbox Code Playgroud)

Aar*_*aid 19

#!/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
Run Code Online (Sandbox Code Playgroud)

这首先作为shell脚本运行.你可以把几乎任何shell代码放在''''和之间# '''.这样的代码将由shell执行.然后,当python在文件上运行时,python将忽略这些行,因为它们看起来像是python的三重引号字符串.

shell脚本测试二进制文件是否存在于路径中which python2 >/dev/null,然后执行它(如果是这样的话)(所有参数都在正确的位置).有关这方面的更多信息,请参阅为什么这个带有shebang#!/ bin/sh和exec python在4个单引号内的片段有效?

注意:该行以4开头,'它们必须'在shell命令的第四个和开头之间没有空格(which...)

  • 只是补充一下:在我的系统上,我必须将 stderr 重定向到 stdout 才能正常工作。`哪个 python2 &gt;/dev/null 2&gt;&amp;1` (2认同)
  • 这是那些过于聪明,也许是危险的聪明的奇妙答案之一。但仍然有效和伟大。 (2认同)