【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 脚本的健壮性与可读性。