bash 脚本会预解析语法吗?

Will bash script pre-parse the syntax?

我正在 运行ning bash 脚本需要 运行 不同的 SunOs 代码和 Linux 我从代码的一部分中得到语法错误那不应该是真的。我没想到,因为我认为 Bash 可以作为解释器。

SunOS 上的 bash 版本是 2.5,Linux 上的版本是 4.1。它抱怨的语法只支持 3.1 版本。

我试图用 "else" 子句禁用较新的代码,但它看起来仍然在预解析。

而且我的脚本第一行有“:”而不是“#!/bin/sh”。

test.sh:

:
echo "`uname`"
if [ `uname` = "SunOS" ]
 then
    echo "do old stuff"
 else
    echo "new stuff"
    arr=($(grep "^X1" ../foo.txt | sed 's/.*=//'))
fi

错误是

> ./test.sh
SunOS
./test.sh: syntax error at line 8: `arr=' unexpected

如果我注释错误行,那么它将正常工作:

:
echo "`uname`"
if [ `uname` = "SunOS" ]
 then
    echo "do old stuff"
 else
    echo "new stuff"
    #arr=($(grep "^X1" ../foo.txt | sed 's/.*=//'))
fi

结果是

> ./test.sh
SunOS
do old stuff

我的问题是如何在不评论的情况下修复此语法错误?我必须 "if/else" 才能在不同的机器上 运行 这个脚本。

您可以将命令放在一个临时变量中,然后在您的条件为真时执行该变量。我只是 运行 我系统上的以下内容:

> if [ true ]; then echo hi; else [blah]=(--4); fi
-bash: syntax error near unexpected token `--4'

如您所述,我遇到语法错误。如果我这样做:

> if [ true ]; then echo hi; else var="[blah]=(--4)" && eval "${var}"; fi
hi

然后回显 hi(没有错误)。最后,如果我这样做:

> if [ ]; then echo hi; else var="[blah]=(--4)" && eval "${var}"; fi
-bash: syntax error near unexpected token `--4'

然后它尝试 运行 代码,并根据尝试 运行 代码生成错误。

bash 至少从第 2 版开始支持该数组语法;如果您在那里遇到错误,那是因为您的脚本根本不是 运行ning 在 bash 下,而是在其他一些 shell 下。这可能与你的脚本以 : 开头而不是 shebang 行有很大关系,这意味着它取决于 运行 脚本来弄清楚 运行 它用什么,用不一致的结果。我强烈建议使用合适的 shebang 系列。如果 bash 不存在于可预测的位置,您可以使用 #!/usr/bin/env bash。如果 bash 可能不在 PATH 中,您可以使用脚本序言 here 之类的东西——一个 #!/bin/sh shebang,然后是命令来查找并切换到 bash.

关于预解析的问题:是的,bash等shell会在执行if之前一直解析到fi关键字构造。他们需要找到 thenelsefi 关键字,以便弄清楚他们将要执行什么以及将要跳过什么,并且为了找到那些他们必须解析他们的方式。