假设我们有一个程序/程序包,它带有自己的解释器和一组脚本,这些脚本/程序应在执行时调用它(使用shebang)。

假设我们要保持其可移植性,因此即使将其简单地复制到其他位置(不同的计算机),也无需调用安装/安装或修改环境(PATH)即可保持其功能。这些脚本不应混入系统解释器。

给定的约束排除了两种已知方法,例如具有绝对路径的shebang:

#!/usr/bin/python

并在环境中搜索
#!/usr/bin/env python

单独的发射器看起来很丑陋,是 Not Acceptable 。

我发现了有关shebang限制的很好的摘要,这些限制描述了为什么shebang中的相对路径是无用的,并且解释器不能有多个参数:http://www.in-ulm.de/~mascheck/various/shebang/

我还为大多数语言找到了practical solutions,并带有“多行shebang”技巧。它允许编写如下脚本:
#!/bin/sh
"exec" "`dirname $0`/python2.7" "$0" "$@"
print copyright

但是有时候,我们不想扩展/修补现有的依赖shebang的脚本,而该脚本具有使用此方法解释器的绝对路径。例如。 Python的setup.py支持--executable选项,该选项基本上允许为其生成的脚本指定shebang内容:
python setup.py build --executable=/opt/local/bin/python

因此,特别地,可以为--executable=指定什么以实现所需的可移植性?或者换句话说,由于我想让这个问题不太针对于Python ...

问题

如何编写一个Shebang,它指定一个解释器,该解释器的路径相对于要执行的脚本的位置?

最佳答案

直接写在shebang中的相对路径是相对于当前工作目录的,因此,像#!../bin/python2.7这样的东西对于除少数目录以外的任何其他工作目录均不起作用。
由于OS不支持它,为什么不使用外部程序,例如使用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,$_)
从21 Jan21更新:
使用更新的env实用程序:
$ env --version | grep env
env (GNU coreutils) 8.30
$ env --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Set each NAME to VALUE in the environment and run COMMAND.

Mandatory arguments to long options are mandatory for short options too.
  -i, --ignore-environment  start with an empty environment
  -0, --null           end each output line with NUL, not newline
  -u, --unset=NAME     remove variable from the environment
  -C, --chdir=DIR      change working directory to DIR
  -S, --split-string=S  process and split S into separate arguments;
                        used to pass multiple arguments on shebang lines
因此,将-S传递给env就可以了

关于python - 相对shebang : How to write an executable script running portable interpreter which comes with it,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33225082/

10-11 09:23