首页 文章

在意外令牌附近混淆语法错误'done'

提问于
浏览
6

我正在尝试学习shell脚本,所以我创建了一个简单的脚本,其循环不执行任何操作:

#!/bin/bash
names=(test test2 test3 test4)
for name in ${names[@]}
do
        #do something
done

但是,当我运行此脚本时,我收到以下错误:

./test.sh:line 6:意外令牌完成附近的语法错误'./test.sh:line 6:done'

我错过了什么? shell脚本'tab敏感'?

6 回答

  • 4

    不,shell脚本不是标签敏感的(除非你做了一些非常疯狂的事情,你在这个例子中没有这样做) .

    你不能有一个空的 while do done 块,(注释不计)尝试替代 echo $name 而不是

    #!/bin/bash
    names=(test test2 test3 test4)
    for name in ${names[@]}
    do
           printf "%s " $name
    done
    printf "\n"
    

    output

    test test2 test3 test4
    
  • 6

    在这种情况下, dashbash 有点脑死亡,它们不允许空循环,所以你需要添加一个no op命令才能运行,例如 true: . 我的测试表明 : 有点快,although they should be the same,不知道为什么:

    time (i=100000; while ((i--)); do :; done)
    

    平均需要 0.262 秒,而:

    time (i=100000; while ((i--)); do true; done)
    

    需要 0.293 秒 . 有趣的是:

    time (i=100000; while ((i--)); do builtin true; done)
    

    需要 0.356 秒 .

    所有测量均为30次运行的平均值 .

  • 1

    Bash有一个内置的no-op冒号(:),它比生成另一个运行 true 的进程更轻量级 .

    #!/bin/bash
    names=(test test2 test3 test4)
    for name in "${names[@]}"
    do
        :
    done
    

    编辑:威廉正确地指出 true 也是一个内置的shell,所以把这个答案作为另一个选项FYI,不是比使用true更好的解决方案 .

  • 1

    你可以用'true'代替任何东西 .

  • 7

    你需要在你的循环中有一些东西,否则bash抱怨 .

  • 1

    某些版本的bash在Windows上编辑脚本时会出现此错误,因此脚本实际上如下所示:

    #!/bin/bash^M
    names=(test test2 test3 test4)^M
    for name in ${names[@]}^M
    do^M
           printf "%s " $name^M
    done^M
    printf "\n"^M
    

    其中^ M表示回车符(0x0D) . 通过使用二进制选项可以很容易地在vi中看到这一点,如:

    vi -b script.sh
    

    要删除那些回车符,只需使用vi命令:

    1,$s/^M//
    

    (注意上面的^ M是一个回车符,在编辑器中使用顺序Control-V Control-M输入它)

相关问题