相对shebang:如何编写一个运行它的可移植解释器的可执行脚本

比方说,我们有一个程序/软件包,它有自己的解释器和一组脚本,应该在执行时调用它(使用shebang)。

假设我们想保持它的可移植性,即使只是复制到不同的位置(不同的机器),它仍然可以运行,而不需要调用setup / install或者修改环境(PATH)。 系统解释器不应该混入这些脚本。

给定的约束条件不包括像绝对path这样的已知方法:

#!/usr/bin/python 

并在环境中search

 #!/usr/bin/env python 

单独的发射器看起来很丑,不能接受。

我发现了很好的总结了shebang局限性,这些局限性描述了为什么shebang中的相对path是无用的,解释者不能有多于一个参数: http : //www.in-ulm.de/~mascheck/various/shebang/

而且我也用“多线社帮”技巧find了大多数语言的实用解决scheme 。 它允许写这样的脚本:

 #!/bin/sh "exec" "`dirname $0`/python2.7" "$0" "$@" print copyright 

但是有时候,我们不希望用这种方法来扩展/修补依赖于shebang的现有脚本和绝对path的解释器。 例如,Python的setup.py支持--executable选项,它基本上允许为它生成的脚本指定shebang内容:

 python setup.py build --executable=/opt/local/bin/python 

所以,特别是,可以指定--executable=为了使所需的种类的可移植性? 或换句话说,因为我想保持这个问题不是太具体到Python …

这个问题

如何写一个指定解释器的shebang,其path与正在执行的脚本的位置有关?

直接在shebang中写入的相对路径是相对于当前工作目录处理的,所以像#!../bin/python2.7这样的东西对其他工作目录来说是不会有效的,除非少数。

由于操作系统不支持它,为什么不使用外部程序就像使用env进行PATH查询。 但是我知道没有专门的程序来计算参数的相对路径,并执行结果命令,除了shell本身和其他脚本引擎。

但是试图在shell脚本中计算路径

 #!/bin/sh -c '`dirname $0`/python2.7 $0' 

不工作,因为在Linux上,shebang仅受一个参数的限制。 这就建议我寻找脚本引擎,它接受脚本作为命令行的第一个参数,并能够执行新的过程:

使用AWK

 #!/usr/bin/awk BEGIN{a=ARGV[1];sub(/[a-z_.]+$/,"python2.7",a);system(a"\t"ARGV[1])} 

使用Perl

 #!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python2.7/r,$_)