Linux Shell条件语句全面整理

一、基础测试命令

1. test 命令

# 基本语法
test 表达式
# 或
test -f file.txt

# 返回值
# 条件为真时返回0,为假时返回非0
test "abc" = "abc"
echo $?  # 输出0(真)

# 常用操作符:
# 字符串:=, !=, -z, -n
# 文件:-e, -f, -d, -r, -w, -x
# 数值:-eq, -ne, -lt, -le, -gt, -ge

2. [ ](单方括号)

# test命令的另一种形式,注意空格!
[ 表达式 ]
[ $a -eq $b ]

# 示例
a=10
b=20
if [ $a -lt $b ]; then
    echo "a小于b"
fi

3. [[ ]](双方括号)

# bash的扩展测试命令,功能更强大
[[ 表达式 ]]

# 示例
if [[ $str == "hello" ]]; then
    echo "字符串匹配"
fi

4. (( ))(双括号)

# 专门用于数值计算和比较
(( 算术表达式 ))

# 示例
a=5
b=10
if (( a < b )); then
    echo "a小于b"
fi

二、详细用法对比

字符串比较

操作 test / [ ] [[ ]] 说明
相等 "$a" = "$b" $a == $b [[ ]]==是模式匹配
不等 "$a" != "$b" $a != $b
为空 -z "$a" -z $a 检查空字符串
非空 -n "$a" -n $a 检查非空字符串
模式匹配 不支持 [[ $a == a* ]] 支持通配符
正则匹配 不支持 [[ $a =~ ^a.* ]] 支持正则表达式

数值比较

操作 test / [ ] (( )) [[ ]] 说明
等于 $a -eq $b a == b a -eq b
不等于 $a -ne $b a != b a -ne b
小于 $a -lt $b a < b a -lt b
小于等于 $a -le $b a <= b a -le b
大于 $a -gt $b a > b a -gt b
大于等于 $a -ge $b a >= b a -ge b

文件测试

测试条件 说明 三种语法通用
-e file 文件/目录是否存在
-f file 是否为普通文件
-d file 是否为目录
-r file 是否可读
-w file 是否可写
-x file 是否可执行
-s file 文件大小是否>0
-L file 是否为符号链接
-O file 是否属于当前用户

逻辑运算符

运算符 test / [ ] [[ ]] (( )) 说明
-a&&(需转义) && &&
-o||(需转义) || ||
! ! !
分组 不支持 ( ) ( )

三、关键注意事项

[ ] 使用陷阱

# 1. 必须加空格
[ "$a" = "$b" ]    # ✓ 正确
["$a" = "$b"]      # ✗ 错误

# 2. 变量必须用引号包围
str="hello world"
[ -n $str ]        # ✗ 可能出错(参数过多)
[ -n "$str" ]      # ✓ 正确

# 3. 字符串比较用=而不是==
[ "$a" = "$b" ]    # ✓ 正确(POSIX标准)

# 4. 不支持&&和||,只能-o和-a
[ "$a" = "yes" -a "$b" = "no" ]  # ✓
[ "$a" = "yes" && "$b" = "no" ]  # ✗(需要转义\&\&)

# 5. 不支持正则和模式匹配

[[ ]] 优点和注意点

# 1. 变量可不加引号(不会分词)
str="hello world"
[[ -n $str ]]      # ✓ 安全

# 2. 支持&&和||
[[ $a == "yes" && $b == "no" ]]  # ✓

# 3. 支持模式匹配
[[ $file == *.txt ]]            # ✓
[[ $name == [A-Z]* ]]           # ✓

# 4. 支持正则表达式
[[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]  # ✓

# 5. 字符串比较可用==或=
[[ "$a" == "$b" ]]  # ✓(==在[[ ]]中是字符串比较)

# 注意:是bash扩展,其他shell可能不支持

(( )) 专用特性

# 1. 专门用于算术运算
(( a = 5 + 3 ))      # ✓ 赋值
(( a++ ))            # ✓ 自增
(( result = a * b )) # ✓ 计算

# 2. 变量可不加$前缀
a=5
b=10
(( a < b ))          # ✓ 等同于(( $a < $b ))

# 3. 支持C语言风格的运算符
(( a += 5 ))         # ✓
(( a = b > 5 ? 10 : 20 ))  # ✓ 三元运算符

# 4. 返回值:表达式为0时返回1(假),非0时返回0(真)
(( 0 ))              # 返回1(假)
(( 1 ))              # 返回0(真)
(( 5 > 3 ))          # 返回0(真)

四、综合对比表

特性 test / [ ] [[ ]] (( ))
Shell支持 POSIX标准,所有shell bash、zsh等 bash、zsh等
变量引号 必须加引号 可不加引号 可不加引号
字符串比较 =!= ==!=、模式匹配 不支持
数值比较 -eq-ne -eq-ne等或==< ==!=<>
模式匹配 不支持 支持(==!= 不支持
正则表达式 不支持 支持(=~ 不支持
逻辑运算符 -a-o! &&||! &&||!
算术运算 不支持 有限支持 完整支持
安全性 容易出错(分词、路径扩展) 安全(不分词、不扩展) 安全
推荐使用场景 可移植脚本 bash脚本(优先使用) 数值计算和比较

五、实用示例

组合使用示例

#!/bin/bash

file="test.txt"
count=5
name="example"

# 复杂的条件判断
if [[ -f "$file" && -r "$file" ]] && (( count > 0 )); then
    echo "文件存在、可读且count大于0"
    
    if [[ $name =~ ^ex.* ]]; then
        echo "名称以ex开头"
    fi
fi

# 多条件判断
a=10
b=20
str="hello"

if (( a < b )) && [[ $str == "hello" ]]; then
    echo "数值比较和字符串比较都通过"
fi

# case语句中的模式匹配
case $file in
    *.txt) echo "文本文件" ;;
    *.sh) echo "shell脚本" ;;
    *) echo "其他文件" ;;
esac

最佳实践建议

  1. bash脚本中优先使用[[ ]],更安全功能更全
  2. 需要可移植时使用[ ],但要注意引号和空格
  3. 数值计算和比较使用(( )),语法更直观
  4. 总是用引号包围[ ]中的变量
  5. 复杂条件用[[ ]]&&\|\|代替-a-o
  6. 文件测试三种语法都可用,选择一致风格

常见错误避免

# 错误示例
[ $var = "test" ]          # var为空时会变成 [ = "test" ]
[[ $var = "test" ]]        # 稍好,但最好还是加引号
[ -f $file ]               # file包含空格时出错

# 正确写法
[ -n "$var" ]              # 检查非空
[ "$var" = "test" ]        # 变量加引号
[[ -f "$file" ]]           # 即使[[ ]]中不加引号通常安全,但文件路径最好加

通过理解这些差异和最佳实践,可以编写更健壮、可读性更强的shell脚本。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐