我正在运行需要为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”才能在不同的机器上运行此脚本。
答案 0 :(得分:3)
至少从版本2开始,bash支持该数组语法;如果你在那里遇到错误,那是因为你的脚本根本没有在bash下运行,而是在其他shell下运行。这可能与您从:
而不是shebang行开始的脚本有很大关系,这意味着它取决于运行脚本以确定运行它的内容,结果不一致。我强烈建议使用合适的shebang系列。如果bash不存在于可预测的位置,则可以使用#!/usr/bin/env bash
。如果bash可能不在PATH
中,您可以使用类似脚本序言here的内容 - #!/bin/sh
shebang,后跟命令查找并切换到bash。
关于预解析的问题:是的,在执行fi
构造之前,bash和其他shell将一直解析为if
关键字。他们需要找到then
,else
和fi
关键字,以便弄清楚他们将要执行的内容以及他们要跳过的内容,以及查找那些他们必须解析他们的方式。
答案 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'
然后它尝试运行代码,并根据尝试运行代码生成错误。