【问题标题】:Shell Script Syntax ErrorShell 脚本语法错误
【发布时间】:2014-05-02 01:21:21
【问题描述】:

目前我正在使用 shell 脚本开发二十一点游戏。我的大部分脚本都使用函数,但是我用来确定播放器/计算机是否崩溃的方法似乎不起作用。谁能指出我正确的方向。 (我是 shell 脚本的新手。)运行它时,它会在以 elif 开头的行周围抛出语法错误,有时会在 if 开头。它还会打印 bustConfirm 中的所有“echo”输出,而不是仅打印正确的输出。

也是的,我的一个函数叫做 bustCheck。

bustConfirm(){
bust='bust'
under='under'

if [ $userBust -eq $bust -a $systemBust -eq $bust ]
then
    echo "You both went bust! Be more careful!" 
    endGameRepeat
elif  [ $userBust -eq $bust -a $systemBust -eq $under ]
    echo $userName "went bust! Congratulations" $systemName"!"
    endGameRepeat
elif  [ $userBust -eq $under -a $systemBust -eq $bust ]
then
    echo $systemName "went bust! Congratulations" $userName"!"
    endGameRepeat
else
    echo "Nobody went bust! Well played!"
    endGameScores
fi
}



bustCheck(){
if [ "$userScore" -gt 21 ]
then
    echo $userName "is bust!"
    userBust='bust'
else
    userBust='under'
fi

if [ "$systemScore" -gt 21 ]
then
    echo $systemName "is bust!"
    systemBust='bust'
else
    systemBust='under'
fi      
bustConfirm

}

我的想法是我想在 bustConfirm 函数中使用 &&,然后使用 ||如果只有其中一个被破坏,则获得玩家被破坏或系统被破坏的结果。

也只是一个指针,但在 bustCheck 中,我看到 userBust 和 systemBust 包含单词 bust 或 under。我为 bustConfirm 函数创建了变量 bust 和 under。

systemScore、userScore、systemName 和 userName 在脚本运行之前设置。 希望我已经提供了足够的详细信息并正确格式化了它,首先是正确的帖子,如果没有,我深表歉意!

【问题讨论】:

  • 括号后面的空格?是的,我刚刚看到,当我把它放进去时,我实际上已经尝试过带和不带空格,所以我现在在这段代码中放了一个,只是为了表明这不是问题。此外,我刚刚看到了 Pitfall 11 段落,我将在明天测试我在这里获得的任何帮助时尝试使用该语法。非常感谢。

标签: bash shell variables syntax


【解决方案1】:

快速浏览一下,我发现第一个 if 语句在左方括号后没有空格。

我还建议您在if 语句中为变量名加上引号。这是由于 shell 的实际工作方式。 bash shell 非常智能,在您的程序有机会做任何事情之前,它会抓取线路,施展魔法,然后将线路呈现给处理器。

例如:

foo=""
if [ $foo = "" ]
then
   echo "Foo is blank"
fi

看起来很简单。但是,发生的情况是您的 shell 将抓取该行,将 $foo 的值替换为字符串“$foo”,然后执行该行。由于$foo 为空白,您的if 语句将变为:

if [ = "" ]   # That's not right!
then
   echo "Foo is blank"
fi

通过使用引号,这是:

foo=""
if [ "$foo" = "" ]
then
   echo "Foo is blank"
fi

变成:

foo=""
if [ "" = "" ]
then
   echo "Foo is blank"
fi

这是有效的。您可以做的另一件事是使用使用双方括号的 new 测试格式:

foo=""
if [[ $foo = "" ]]
then
   echo "Foo is blank"
fi

即使没有额外的引号,这也始终有效,现在推荐使用,除非您的程序必须与原始 Bourne shell 语法兼容。

您在调试 shell 脚本时还可以做的另一件事是使用set -xv,它会打开详细调试。每一条语句,在执行之前都会被打印,然后在shell填充变量、模式等之后再次打印,然后执行。这是调试程序的好方法。在你想要这种详细的调试模式之前,只需将set -xv 放在行上,然后使用set +xv 将其关闭。 (是的,- 将其打开,+ 将其关闭。)


非常感谢大卫,很好的回答,您能否告诉我在此范围内获得 && 或等价物的最佳方法是什么,因为我需要确定它们是否都破产了,或者只是一个等等

正如评论中已经提到的,您可以使用以下两种形式之一:

if [ "$foo" = "bar" ] && [ "$bar" = "foo" ]

if [[ $foo = "bar" && $bar = "foo" ]]

【讨论】:

  • 非常感谢大卫,很好的回答,你能不能告诉我在这个范围内获得 && 或等价物的最佳方法是什么,因为我需要找出它们是否都是半身像,或者只是一个等.
  • @CanadaBornAndBred 您可以使用if [ "$foo" = bar ] && [ "$bar" = foo ]if [[ $foo == bar && $bar == $foo ]](避免使用-a-o,它们已过时(请参阅here 为什么)。
猜你喜欢
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 2013-10-07
  • 2014-01-28
相关资源
最近更新 更多