为什么Shell脚本与悬空'}'?一起运行

时间:2016-09-27 14:19:08

标签: bash shell scripting

我编写了这个脚本,用一个命令编译和运行我的C和java程序。

     1   run(){
     2      gcc -lm $1 && ( shift; ./a.out $* )
     3     }
     4
     5   jrun(){
     6      clas=`echo $1 | cut -d'.' -f1 `
     7      javac $1 && { shift; java $clas $* }
     8   }

但是在跑步时遇到错误。

# source t.sh
-bash: t.sh: line 9: syntax error: unexpected end of file

当我在最后添加'}'时,脚本成功运行。

刚才意识到我在{}中使用了()而不是line 7

我的问题是为什么它可以与一个悬挂的'}'一起运行并正常工作?

3 个答案:

答案 0 :(得分:5)

$*之后你需要一个分号来分隔大括号。实际上,它只是被解释为javac的参数。

顺便说一下,你可能正在寻找

run(){
   gcc -lm "$1" || return
   shift
   ./a.out "$@"
   }

jrun(){
   javac "$1" || return
   local clas=${1%.*}
   shift
   java "$clas" "$@"
 }

修复了许多引用问题,并避免了稍微笨拙的复合命令。 local声明阻止函数破坏具有相同名称的全局变量,但它是一种基础。

答案 1 :(得分:3)

问题在于您的阻止 - 您错过了分号。

可以使用此示例复制:

SnakeGame

如果在交互式终端中运行此命令,shell将等待接收进一步的输入。如果输入额外的右括号,则会看到true && { echo } # missing semicolon 的输出:

echo }

由于shell解析的方式,在块的结尾之前,最后一个语句和大括号之间需要有换行符或分号。

}

答案 2 :(得分:3)

  

我的问题是为什么它可以用一个d''来运行和工作?

没有。您提供的代码缺少一个}。您需要在bash接受之前添加一个。

问题出在第7行:

    javac $1 && { shift; java $clas $* }

{}不是shell元字符。它们的重要性取决于背景,特别是它们可以看起来不具有普遍的贝壳词语。因此,错误行上的}java命令的参数,而不是右括号。你想要这个:

    javac $1 && { shift; java $clas $*; }

或者这个:

    javac $1 && {
      shift
      java $clas $*
    }

或其中的一些变体。