bash脚本会预先解析语法吗?

时间:2018-01-22 20:36:38

标签: bash solaris

我正在运行需要为SunOs和Linux运行不同代码的bash脚本,并且我从代码中不应该为真的部分得到语法错误。我没想到,因为我认为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”才能在不同的机器上运行此脚本。

2 个答案:

答案 0 :(得分:3)

至少从版本2开始,bash支持该数组语法;如果你在那里遇到错误,那是因为你的脚本根本没有在bash下运行,而是在其他shell下运行。这可能与您从:而不是shebang行开始的脚本有很大关系,这意味着它取决于运行脚本以确定运行它的内容,结果不一致。我强烈建议使用合适的shebang系列。如果bash不存在于可预测的位置,则可以使用#!/usr/bin/env bash。如果bash可能不在PATH中,您可以使用类似脚本序言here的内容 - #!/bin/sh shebang,后跟命令查找并切换到bash。

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

答案 1 :(得分:1)

您可以将命令粘贴到临时变量中,然后在条件为真时执行变量。我刚刚在我的系统上运行了以下内容:

> 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

然后它回声嗨(没有错误)。最后,如果我这样做:

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

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