bash脚本,第30行:语法错误:意外的文件结束

时间:2010-10-27 10:15:00

标签: linux bash shell

我写了一些脚本,并有意外的文件结尾

echo off
if [$JAVA_HOME = ""]; then goto no_java_home fi
if [$SRV_HOME = ""]; then  goto no_srv_home fi
echo Uses JAVA_HOME=$JAVA_HOME
echo Uses SRV_HOME=$SRV_HOME
export ACP=""
export ACP=$ACP;$JAVA_HOME/lib/tools.jar
export ACP=$ACP;$SRV_HOME/ant/lib/ant.jar
export ACP=$ACP;$SRV_HOME/ant/lib/ant-launcher.jar
export ACP=$ACP;$SRV_HOME/ant/lib/ant-nodeps.jar
export ACP=$ACP;$SRV_HOME/ant/lib/optional.jar
export ACP=$ACP;$SRV_HOME/ant/lib/ant-contrib-1.0b3.jar
$JAVA_HOME/bin/java -Xmx512m -classpath $ACP org.apache.tools.ant.Main -buildfile $SRV_HOME/ant/ant_script.xml %*
goto ends

no_srv_home:
clear
echo "You should set the TMX_HOME environment variable. For example: TMX_HOME=d:\MYSERVER"
goto ends

no_java_home:
clear
echo "You should set the JAVA_HOME environment variable"
goto ends
ends: echo "OK"

我的问题在哪里?

3 个答案:

答案 0 :(得分:4)

您的问题是您的脚本看起来像bash和cmd语法的随意混合。这是一个bash脚本。

if [ "$JAVA_HOME" = "" ]; then
  echo 1>&2 "$0: You need to set the JAVA_HOME variable, e.g.: export JAVA_HOME='c:/java'"
  exit 2
fi
if [ "$SRV_HOME" = "" ]; then
  echo 1>&2 "$0: You need to set the SRV_HOME variable, e.g.: export SRV_HOME='d:/myserver'"
  exit 2
fi
echo "$0: Uses JAVA_HOME=$JAVA_HOME"
echo "$0: Uses SRV_HOME=$SRV_HOME"
ACP="$JAVA_HOME/lib/tools.jar"
for x in ant ant-launcher ant-nodeps optional ant-contrib-1.0b3; do
  ACP="$ACP;$SRV_HOME/ant/lib/$x.jar"
done
"$JAVA_HOME/bin/java" -Xmx512m -classpath "$ACP" \
                      org.apache.tools.ant.Main \
                      -buildfile "$SRV_HOME/ant/ant_script.xml" \
                      "$@"

以下列出了我已纠正的事项:

  • Bash有结构化编程结构(块,条件,循环)。它没有goto。
  • 测试命令[ … ]在括号的每一侧都需要空格(除了标点;之外)。
  • 所有变量替换($foo)都应该是双引号(否则如果变量的值包含某些特殊字符(如空格),shell将会执行奇怪的操作。)
  • 错误消息应显示在错误输出上:echo 1>&2 "this is an error message"。 (这也适用于cmd脚本。)
  • 如果发生错误,脚本应返回非零状态。 (这也适用于cmd脚本。)
  • 由于ACP是内部脚本变量,因此无需将其导出到环境中。
  • ;是一个特殊字符,因此当您想在字符串中使用它时必须引用它。
  • (可选)您可以避免使用循环多次重复相同的字符串(bash中的循环没有他们在cmd中的疯狂限制)。
  • Cmd的%*是bash的"$@"
  • (可选)如果您的脚本被另一个名为etc的脚本调用,那么在每条错误消息中都有一个脚本名称$0
  • (可选)您可以在行尾用反斜杠打破一个长命令行。

答案 1 :(得分:2)

转到,真的吗?

更改if语句以在fi

之前添加分号
if [$JAVA_HOME = ""]; then goto no_java_home ; fi

例如。

你的shell无法区分no_java_home命令和fi命令,因为它们出现在同一行,没有分号分隔符或任何其他结束语句的内容。你的线路上有同样的问题,有清晰的回声;就sh而言,回声在这里被用作清除的参数,而不是一个单独的命令。

但是请不要使用goto重写这个!

像这样:

if [$JAVA_HOME = ""] ; then
        clear
        echo "You should set the JAVA_HOME environment variable"
elif [$SRV_HOME = ""] ; then
        clear
        echo "You should set the TMX_HOME environment variable. For example: TMX_HOME=d:\MYSERVER"
else
        echo Uses JAVA_HOME=$JAVA_HOME

        echo Uses SRV_HOME=$SRV_HOME

        export ACP=""

        export ACP=$ACP;$JAVA_HOME/lib/tools.jar

        export ACP=$ACP;$SRV_HOME/ant/lib/ant.jar

        export ACP=$ACP;$SRV_HOME/ant/lib/ant-launcher.jar

        export ACP=$ACP;$SRV_HOME/ant/lib/ant-nodeps.jar

        export ACP=$ACP;$SRV_HOME/ant/lib/optional.jar

        export ACP=$ACP;$SRV_HOME/ant/lib/ant-contrib-1.0b3.jar

        $JAVA_HOME/bin/java -Xmx512m -classpath $ACP org.apache.tools.ant.Main -buildfile

        $SRV_HOME/ant/ant_script.xml %*
fi

echo "OK"

答案 2 :(得分:0)

如果以不同方式重写以下行,则意外结束文件错误。

原帖:

if [$JAVA_HOME = ""]; then goto no_java_home fi    
if [$SRV_HOME = ""]; then goto no_srv_home fi 

更新:

if [$JAVA_HOME = ""]; then 
  goto no_java_home 
fi

if [$SRV_HOME = ""]; then 
  goto no_srv_home 
fi