我正在尝试学习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敏感'?
不,shell脚本不是标签敏感的(除非你做了一些非常疯狂的事情,你在这个例子中没有这样做) .
你不能有一个空的 while do done 块,(注释不计)尝试替代 echo $name 而不是
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
在这种情况下, dash 和 bash 有点脑死亡,它们不允许空循环,所以你需要添加一个no op命令才能运行,例如 true 或 : . 我的测试表明 : 有点快,although they should be the same,不知道为什么:
dash
bash
true
:
time (i=100000; while ((i--)); do :; done)
平均需要 0.262 秒,而:
0.262
time (i=100000; while ((i--)); do true; done)
需要 0.293 秒 . 有趣的是:
0.293
time (i=100000; while ((i--)); do builtin true; done)
需要 0.356 秒 .
0.356
所有测量均为30次运行的平均值 .
Bash有一个内置的no-op冒号(:),它比生成另一个运行 true 的进程更轻量级 .
#!/bin/bash names=(test test2 test3 test4) for name in "${names[@]}" do : done
编辑:威廉正确地指出 true 也是一个内置的shell,所以把这个答案作为另一个选项FYI,不是比使用true更好的解决方案 .
你可以用'true'代替任何东西 .
你需要在你的循环中有一些东西,否则bash抱怨 .
某些版本的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输入它)
6 回答
不,shell脚本不是标签敏感的(除非你做了一些非常疯狂的事情,你在这个例子中没有这样做) .
你不能有一个空的
while do done
块,(注释不计)尝试替代echo $name
而不是output
在这种情况下,
dash
和bash
有点脑死亡,它们不允许空循环,所以你需要添加一个no op命令才能运行,例如true
或:
. 我的测试表明:
有点快,although they should be the same,不知道为什么:平均需要
0.262
秒,而:需要
0.293
秒 . 有趣的是:需要
0.356
秒 .所有测量均为30次运行的平均值 .
Bash有一个内置的no-op冒号(:),它比生成另一个运行
true
的进程更轻量级 .编辑:威廉正确地指出
true
也是一个内置的shell,所以把这个答案作为另一个选项FYI,不是比使用true更好的解决方案 .你可以用'true'代替任何东西 .
你需要在你的循环中有一些东西,否则bash抱怨 .
某些版本的bash在Windows上编辑脚本时会出现此错误,因此脚本实际上如下所示:
其中^ M表示回车符(0x0D) . 通过使用二进制选项可以很容易地在vi中看到这一点,如:
要删除那些回车符,只需使用vi命令:
(注意上面的^ M是一个回车符,在编辑器中使用顺序Control-V Control-M输入它)