意外令牌“完成”附近的语法错误令人困惑

时间:2012-05-10 12:38:52

标签: bash shell syntax for-loop syntax-error

我正在尝试学习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脚本的标签敏感'?

6 个答案:

答案 0 :(得分:7)

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

你不能有一个空的while do done块,(评论不计算在内) 尝试替换echo $name代替

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

<强>输出

test test2 test3 test4

答案 1 :(得分:6)

在这种情况下,

dashbash有点脑死亡,它们不允许空循环,所以你需要添加一个no op命令才能运行,例如true:。我的测试表明:有点快,although they should be the same,不确定原因:

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

n平均需要0.262秒,而:

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

需要0.293秒。有趣的是:

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

需要0.356秒。

所有测量平均为30次。

答案 2 :(得分:4)

Bash有一个内置的no-op,冒号(:),它更轻巧 而不是产生另一个进程来运行true

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

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

答案 3 :(得分:1)

您可以使用'true'替换所有内容。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

#!/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输入它)