2

我正在尝试编写一个从 shebang 行调用的脚本,并根据条件(在我的情况下,基于操作系统版本)返回正确的解释器,但我不明白为什么它不起作用。
我将尝试通过一个示例来澄清:
可执行文件 1:/home/orens/dynamically_select_interpreter/select_interpreter.sh:

#!/usr/bin/env bash
echoerr() { echo "$@" 1>&2; }

interpreter=`cat /home/orens/dynamically_select_interpreter/interpreter`
if [ -z "$interpreter" ]; then
  echoerr "Could not find interpreter!"
  exit 1
fi

echoerr "Found interpreter: $interpreter"

exec "$interpreter" "$@"

该脚本根据某些文件的内容选择解释器(在这种情况下,内容是:)/usr/bin/python。然后,它通过调用将自己替换为正确的解释器exec
从命令行调用它,这就是我得到的:

$ /home/orens/dynamically_select_interpreter/select_interpreter.sh
Found interpreter: /usr/bin/python
Python 2.4.3 (#1, Dec 10 2010, 17:24:35)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

但是,当我尝试在 shebang 行中使用它时,如下所示:

#!/home/orens/dynamically_select_interpreter/select_interpreter.sh


echo $SHELL # should be an error # LINE 1
import sys; print "HERE"; print sys.version # this is the actual error # LINE 2

该脚本作为 shell 脚本而不是 python 脚本执行。LINE 1 正确执行,而 LINE 2 引发错误。看起来 shebang 行被默默地忽略了(甚至打印到 stderr 也没有显示在屏幕上)。

基本上,我正在尝试做与 相同的操作env,但来自脚本。我想如果我用 C/C++ 编写并编译它,我会得到我想要的,但是由于这个脚本将被用作克服多内核版本情况的工具,我真的希望我的可执行文件是 OS-独立的,我实现这一目标的唯一方法是通过脚本。

任何人都可以解释这种行为或帮助我解决它吗?

谢谢!

4

3 回答 3

2

检查execve手册页

解释器必须是本身不是脚本的可执行文件的有效路径名。

(强调我的)

于 2013-01-20T19:10:13.337 回答
1

额外的重定向是否有效取决于您的操作系统。您的示例(略微简化,但想法保持不变)适用于我的 Debian 安装。但是某些操作系统在解释 shebang 行的方式上存在限制,包括对命令长度、命令可能采用的参数数量等的限制。查看此讨论以获取一些示例——它们使用 PERL,但基本上尝试执行和你一样。sourceforge 上有一个名为shebang-wrapper的项目,它可能会有所帮助,但我还没有在实践中对其进行测试,它仍处于 pre-alpha 阶段。

于 2013-01-20T18:31:36.373 回答
0

您的行: exec "$interpreter" "$@" 不包括要执行的脚本,只包括参数。

试试: exec "$interpreter" $0 $@

#!/bin/bash
echo "PRE:$0 $@"
if [ "$1" != "--" ]; then
  i=$1
  exec $i $0 -- $@
else
  shift; shift
fi
echo "POST:$0 $@"

bll-desktop:bll$ ./t.sh /bin/sh b c
PRE:./t.sh /bin/sh b c
PRE:./t.sh -- /bin/sh b c
POST:./t.sh b c
bll-desktop:bll$ ./t.sh /bin/bash b c
PRE:./t.sh /bin/bash b c
PRE:./t.sh -- /bin/bash b c
POST:./t.sh b c
bll-desktop:bll$
于 2013-01-21T02:51:24.057 回答