我正在尝试学习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脚本的标签敏感'?
答案 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)
dash
和bash
有点脑死亡,它们不允许空循环,所以你需要添加一个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输入它)