每日Linux学习:脚本学习 [ ] 与 [ [ ] ] 的区别

一、背景知识

[ ] 源于 1970 年代的 Bourne shell(test 命令),而 [[ ]] 是 1980 年代 ksh 的创新,后被 Bash 采纳。现代 Bash 中 [ 已是内置命令,但处理逻辑仍保持 POSIX 兼容性。

现代 Bash 脚本(#!/bin/bash),优先使用 [[]](更安全、功能更强)。

POSIX 兼容脚本(#!/bin/sh),使用 [] 并严格遵循很多规则,如:

[ -n "$var" ] && [ "$var" != "ERROR" ]

#所有变量加双引号

#逻辑组合用 && 或 || 连接多个 []


二、关键区别详解及实例

1、字符串比较(含空变量)

str="Hello World"

empty=""

# [ ] 必须加引号,否则空变量报错

if [ "$empty" = "" ]; then # 正确写法

echo "[]: Empty string"

fi

# [[ ]] 自动处理空变量

if [[ $empty == "" ]]; then # 无需引号

echo "[[]]: Empty string"

fi


2、模式匹配(通配符)

file="image.jpg"

# [[ ]] 支持通配符扩展

if [[ $file == *.jpg ]]; then

echo "[[]]: JPEG file"

# [ ] 不支持通配符(需外部命令如 `case`)

if [ "$file" = "*.jpg" ]; then # 字面比较 *.jpg

echo "[]: This will NOT match"

fi


3、正则表达式匹配(仅 [[]] 支持)

email="user@example.com"

if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then

echo "[[]]: Valid email"

fi


4、逻辑运算符

num=15

# [] 必须用 -a/-o(或转义 &&/||)

if [ $num -gt 10 -a $num -lt 20 ]; then

echo "[]: 10 < num < 20"

# [[]] 支持原生 && 、||

if [[ $num > 10 && $num < 20 ]]; then

echo "[[]]: 10 < num < 20 "

fi


5、数字运算

a=10

b=2

# [] 必须用 -gt/-lt

if [ $a -gt $b ]; then

echo "[]: a > b"

# [[]] 支持数学符号(但实际按字符串比较!)

if [[ $a > $b ]]; then # 按字典序比较,"10" < "2"!

echo "This may be WRONG: [[ 10 > 2 ]] is false!"

fi

# 正确方式(数字比较统一用 -gt/-lt)

if [[ $a -gt $b ]]; then

echo "[[]]: Correct: a > b"

fi


6、路径扩展问题

touch "a b.txt" # 创建含空格的文件

# [] 可能误触发路径扩展

if [ -f *.txt ]; then # 若匹配多个文件,报错:[: too many arguments

echo "This may fail"

fi

# [[]] 禁用路径扩展

if [[ -f *.txt ]]; then # *.txt 被视为字面字符串

echo "Safe: [[ -f *.txt ]] checks a file named '*.txt'"

fi


三、更多规则对比见表格

原文链接:,转发请注明来源!