开发工具

Shell 双中括号[[]]

13 篇文章69 次收藏

在 Shell 脚本中,双中括号 [[ ]] 是 Bash、Zsh 等现代 Shell 提供的 增强版条件测试 结构,比传统的 [ ] 更强大且安全。以下是详细解析和示例:

1. 字符串比较(支持通配符和正则)

[[ "hello" == h* ]] && echo "Matches pattern"      # 通配符匹配(无需引号)
[[ "file.txt" == *.txt ]] && echo "Is a .txt file" 

# 正则表达式匹配(=~)
[[ "abc123" =~ ^[a-z]+[0-9]+$ ]] && echo "Matches regex"

优势:

右侧的通配符或正则表达式无需引号([ ] 中必须用 * 需引号)。

避免变量未加引号导致的语法错误。


2. 逻辑运算符更直观

[[ -f file.txt && -r file.txt ]]  # 使用 &&(AND)、||(OR)、!(NOT)
[[ ! -d "/tmp" ]]                 # 逻辑非更清晰

对比 [ ]:

[ ] 必须用 -a(AND)、-o(OR),容易与文件测试符混淆。

[[ ]] 的 &&/|| 行为更符合编程习惯。


3. 自动变量解引用(无需引号)

filename="my file.txt"
[[ -f $filename ]]  # 即使文件名含空格也安全

对比 [ ]:

[ ] 中变量必须加引号("$filename"),否则会因空格报错。


4. 支持多条件分组

[[ ($x -gt 5 || $y -lt 10) && $z == "ok" ]]  # 使用括号分组条件


5. 模式匹配扩展

[[ "Linux" == L@(inux|inux) ]]  # 需开启 `extglob`(Bash)


6. 数值比较(兼容 [ ] 的运算符)

[[ 5 -gt 3 ]]      # 传统数值比较(-gt, -le 等)
[[ 5 > 3 ]]        # 也可用数学符号(但注意字符串比较陷阱)


注意:

使用 > 或 < 时,需确保是数值比较(可能被误认为字符串比较)。

注意事项

1、非 POSIX 兼容:[[ ]] 是 Bash/Zsh 扩展,在纯 sh 中不可用。


2、空格规则:

[[ $var == value ]]  # 正确(内部空格可选)
[[$var == value]]    # 错误(首尾必须空格)


3、避免解析歧义:

[[ 5 > 10 ]]        # 字符串比较(按字典序,"5" > "10")
[[ 5 -gt 10 ]]      # 数值比较(推荐)

与 [ ] 的核心区别

特性[[ ]][ ]test
逻辑运算符&&、`
字符串通配符直接支持 == 和 =~需外部工具(如 case
变量引号可省略(安全)必须加引号(否则报错)
模式分组支持 () 分组不支持
POSIX 兼容性仅限 Bash/Zsh所有 Shell 通用

经典用例

# 检查文件是否存在且可读
if [[ -f "/etc/passwd" && -r "/etc/passwd" ]]; then
    echo "File is readable"
fi

# 检查字符串是否匹配正则(如邮箱格式)
email="user@example.com"
if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
    echo "Valid email"
fi


何时选择 [[ ]] vs [ ]?

用 [[ ]] 当:

1、需要通配符/正则匹配

2、脚本已限定为 Bash/Zsh

3、避免引号相关错误

用 [ ] 当:

1、需要兼容 POSIX Shell(如 /bin/sh)

2、脚本需在极简环境(如 Alpine Linux 的 dash)中运行


通过 [[ ]],可以写出更简洁、安全的条件判断代码,尤其在复杂逻辑和字符串处理中优势明显。