我有一些 python-2.x 脚本,我在不同的系统、Debian 和 Arch linux 之间复制它们。Debian 将 python 安装为“/usr/bin/python”,而 Arch 将其安装为“/usr/bin/python2”。一个问题是在 Arch linux 上也存在引用 python-3.x 的“/usr/bin/python”。所以每次我复制一个文件时,我都必须更正 shebang 行,这有点烦人。
在 Arch 我使用
#!/usr/bin/env python2
在Debian上我有
#!/usr/bin/env python
由于 Debian 上不存在“python2”,有没有办法通过首选应用程序?也许有一些外壳扩展?例如,我不介意它是否取决于现有的 '/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”,因为如果我将脚本交给其他人,它就不会运行。我也不想让'python'指向 Arch 上的 python2,因为它会因更新而中断。
有没有一种干净的方法可以在不编写包装器的情况下做到这一点?
我意识到之前有人问过类似的问题,但我没有看到任何符合我的边界条件的答案:) 不同版本 Python 的条件 shebang 行
- - 更新
我拼凑了一个丑陋的外壳解决方案,现在可以完成这项工作。
#!/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
使用标准输入 (-) 的输入启动找到的程序 $p 并传递参数 ($*)
$p - $* <<EOF
...
EOF