Shell:常见错误总结(二)
Blog:博客园 个人
译自BashPitfalls
本文总结了编写Shell脚本中的常见错误。
承接上文。
[ "$foo" = bar && "$bar" = foo ]
不能在test
或者[]
中使用&&
命令。正确方法:
[ bar = "$foo" ] && [ foo = "$bar" ] # Right! (POSIX)
[[ $foo = bar && $bar = foo ]] # Also right! (Bash / Ksh)
[[ $foo > 7 ]]
虽然[[]]
可以做一些数值比较,但不推荐使用,正确方法:
# Bash / Ksh
((foo > 7)) # Right!
[[ foo -gt 7 ]] # Works, but is uncommon. Use ((…)) instead.
# POSIX
[ "$foo" -gt 7 ] # Also right!
[ "$((foo > 7))" -ne 0 ] # POSIX-compatible equivalent to ((, for more general math operations.
💡Tips:在
[[]]
中使用类似>
比较符,bash解释器会将其视为字符串比较。
如果任何算术上下文的输入(包括((
,let
,数组索引)或[[…]]
不能保证包含数字比较的测试表达式,因此必须始终在计算表达式之前验证您的输入:
POSIX
case $foo in
("" | *[!0123456789]*)
printf '$foo is not a sequence of decimal digits: "%s"\n' "$foo" >&2
exit 1
;;
*)
[ "$foo" -gt 7 ]
esac
💡Tips:由于
[/test
这类命令的算数运算符操作的是十进制整数,若二进制010则会被解释为数字10。
grep foo bar | while read -r; do ((count++)); done
该命令咋看还不错,但只是grep -c
很差的实现,而且对count
的更改不会传播到while
循环之外,因为管道中的每个命令都在单独的子shell中执行。
if [grep foo myfile]
许多初学者对if
语句有一种错觉,看到if
关键字后面紧跟[
或[[
这一非常常见的模式。这让人相信[
不知何故是if
语句语法的一部分,就像C语言的if
语句中使用的括号一样。
这种想法是错误的,[
是命令,而不是if
语句的语法标记。它等同于test
命令,不同之处在于最后一个参数必须是]
。例如:
# POSIX
if [ false ]; then echo "HELP"; fi
if test false; then echo "HELP"; fi
if
语法如下:
if COMMANDS; then
<COMMANDS>
elif <COMMANDS>; then # optional
<COMMANDS>
else
<COMMANDS> # optional
fi # required
如果您希望根据grep
命令的输出做出决定,则不希望将其括在圆括号、方括号、反号或任何其他语法中,只需在if
之后使用grep
作为命令,如下所示:
if grep -q fooregex myfile; then
…
fi
如果grep
与myfile
中的一行匹配,那么退出代码将为0(True),然后将执行then
部分。否则,如果没有匹配项,grep
将返回非零值,整个if
命令将为零。
if [bar="$foo"]; then …
[bar="$foo"] # Wrong!
[ bar="$foo" ] # Still wrong!
[bar = "$foo"] # Also wrong!
[[bar="$foo"]] # Wrong again!
[[ bar="$foo" ]] # Guess what? Wrong!
[[bar = "$foo"]] # Do I really need to say it…
以上为错误语法,正确如下:
if [ bar = "$foo" ]; then …
if [[ bar = "$foo" ]]; then …
💡Tips:每对参数之间必须有空格,以便Bash解释器知道每个参数的开始和结束位置。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?