简体   繁体   English

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

[英]Confusing syntax error near unexpected token 'done'

I am trying to learn shell scripting, so I created a simple script with a loop that does nothing: 我正在尝试学习shell脚本,所以我创建了一个简单的脚本,其循环不执行任何操作:

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

however, when I run this script I get the following errors: 但是,当我运行此脚本时,我收到以下错误:

./test.sh: line 6: syntax error near unexpected token done' ./test.sh:第6行:意外令牌完成附近的语法错误'
./test.sh: line 6: done' ./test.sh:第6行:完成'

What have I missed here? 我错过了什么? are shell scripts 'tab sensitive'? shell脚本'tab敏感'?

No, shell scripts are not tab sensitive (unless you do something really crazy, which you are not doing in this example). 不,shell脚本不是标签敏感的(除非你做了一些非常疯狂的事情,你在这个例子中没有这样做)。

You can't have an empty while do done block, (comments don't count) Try substituting echo $name instead while do donewhile 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

dash and bash are a bit brain-dead in this case, they do not allow an empty loop so you need to add a no op command to make this run, eg true or : . 在这种情况下, dashbash有点脑死亡,它们不允许空循环,所以你需要添加一个no op命令才能运行,例如true: My tests suggest the : is a bit faster, although they should be the same , not sure why: 我的测试表明:有点快, 虽然它们应该是相同的 ,但不确定原因:

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

n average takes 0.262 seconds, while: 平均需要0.262秒,而:

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

takes 0.293 seconds. 需要0.293秒。 Interestingly: 有趣的是:

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

takes 0.356 seconds. 需要0.356秒。

All measurements are an average of 30 runs. 所有测量均为30次运行的平均值。

Bash has a built-in no-op, the colon (:), which is more lightweight than spawning another process to run true . Bash有一个内置的no-op冒号(:),它比生成另一个运行true进程更轻量级。

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

EDIT: William correctly points out that true is also a shell built-in, so take this answer as just another option FYI, not a better solution than using true. 编辑:威廉正确地指出, true也是一个内置的shell,所以把这个答案作为另一个选项FYI,不是比使用true更好的解决方案。

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

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

This error is expected with some versions of bash where the script was edited on Windows and so the script actually looks as follows: 某些版本的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

where the ^M represents the carriage-return character (0x0D). 其中^ M表示回车符(0x0D)。 This can easily be seen in vi by using the binary option as in: 通过使用二进制选项可以很容易地在vi中看到这一点,如:

vi -b script.sh

To remove those carriage-return characters simply use the vi command: 要删除那些回车符,只需使用vi命令:

1,$s/^M//

(note that the ^M above is a single carriage-return character, to enter it in the editor use sequence Control-V Control-M) (注意上面的^ M是一个回车符,在编辑器中使用顺序Control-V Control-M输入它)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM