【Shell编程】条件表达式中[]和[[]]的区别
条件表达式中[]和[[]]的区别
在 Linux Shell 脚本中,条件表达式使用的 [ ](单中括号)和 [[ ]](双中括号)存在关键区别,具体如下:
一、基础区别对比
| 特性 | [ ] (单中括号) | [[ ]] (双中括号) | 
|---|---|---|
| 本质 | test命令的另一种形式 | Bash 关键字(非命令,语法更严格) | 
| Shell 支持 | 所有 POSIX Shell (sh、dash) | 仅 Bash(Zsh、Ksh 等扩展 Shell 支持) | 
| 单词分割(Word Splitting) | 进行变量分词(需手动加双引号) | 禁止分词(直接处理带空格字符串更安全) | 
| 逻辑运算符 | -a(AND)、-o(OR) | &&(AND)、` | 
| 模式匹配 | 不支持 | 支持通配符匹配( ==、!=支持 Glob) | 
| 正则匹配 | 不支持 | =~支持正则表达式 | 
| 性能 | 外部命令(稍慢) | 内置关键字(更快) | 
二、典型使用场景对比
- 字符串比较
 • [ ]:需显式保护变量避免空值错误
name=""
if [ "$name" == "John" ]; then     # 必须加双引号,否则语法错误echo "Hello John"
fi
• [[ ]]:自动处理空值更安全
name=""
if [[ $name == "John" ]]; then     # 无需引号echo "Hello John"
fi
- 数值比较
 • [ ]:需使用数值操作符(-eq,-gt)
num=10
if [ $num -gt 5 ]; thenecho "Greater than 5"
fi
• [[ ]]:可使用算数扩展或直接比较
num=10
if [[ $((num)) > 5 ]] || [[ num -gt 5 ]]; thenecho "Greater than 5"
fi
- 复合逻辑
 • [ ]:必须使用-a、-o,括号需转义
age=25
if [ "$age" -gt 18 -a "$age" -lt 30 ]; thenecho "Young adult"
fi
• [[ ]]:支持更直观的 &&、||,括号无需转义
age=25
if [[ $age -gt 18 && $age -lt 30 ]]; thenecho "Young adult"
fi
- 模式匹配
 • [ ]:只能精确匹配
file="demo.txt"
if [ "$file" = "*.txt" ]; thenecho "Text file"              # 不会匹配到,因引号禁用了通配符
fi
• [[ ]]:支持通配符匹配
file="demo.txt"
if [[ $file == *.txt ]]; then     # 通配符匹配成功echo "Text file"
fi
- 正则表达式
 • [ ]:不支持(需外部命令如grep)
email="user@example.com"
if echo "$email" | grep -Eq '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'; thenecho "Valid email"
fi
• [[ ]]:直接支持正则操作符 =~
email="user@example.com"
if [[ $email =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; thenecho "Valid email"
fi
三、关键差异总结
-  安全性 
 •[[ ]]自动处理变量中的空格和特殊字符,无需手动加引号,避免意外错误。• [ ]必须显式使用引号包裹变量,否则空变量或含空格变量会导致语法错误。# 危险示例 file="My Document.txt" [ $file == "My Document.txt" ] # 因空格导致被分割为多个参数,报错 [[ $file == "My Document.txt" ]] # 正确处理
-  功能扩展 
 • 模式匹配:[[ ]]的==/!=支持*、?等通配符。• 正则表达式: [[ ]]的=~操作符支持正则匹配。• 逻辑组合: [[ ]]支持类似编程语言的&&、||更直观。
-  性能优势 
 由于[[ ]]是 Bash 内置关键字,不需要生成子进程执行外部test,因此执行效率更高。
四、选用原则
 • 推荐使用 [[ ]]:
• 脚本明确使用 #!/bin/bash 解释器。
• 需要更安全的变量处理或高级模式匹配。
• 需要使用 [ ]:
• 保证 POSIX Shell 兼容性(如 /bin/sh)。
• 脚本需在非 Bash 环境(如 Dash)运行。
五、扩展知识
 • 不支持 [[ ]] 的 Shell
在 sh 或 dash 中运行含 [[ ]] 的脚本会报错:
$ dash script.sh
syntax error: unexpected "("
• (( )) 与数值运算
对于数值比较,还可使用 (( )) 关键字:
num=5
if (( num > 3 && num < 10 )); then  # 更数学化的比较语法echo "Within range"
fi
掌握这些区别可提升 Shell 脚本的健壮性与可读性。
