当前位置: 首页 > ds >正文

Shell 脚本条件测试

Shell 脚本条件测试

6.1 条件测试简介

在 Shell 脚本中,我们经常需要做条件判断,根据不同的测试结果执行不同的操作。这就像是在问问题,然后根据“是”或“否”来决定下一步做什么。

执行条件测试后:

  • 返回 0 表示“真”(条件成立)
  • 返回非0 表示“假”(条件不成立)

条件测试的五种语法格式

  1. test <表达式>
    test 命令后需要加空格再写表达式
  2. [ <表达式> ]推荐使用👍)
    test 等效,方括号内两端需要有空格
  3. [[ <表达式> ]]
    功能更强的扩展版本,两端也需要空格
  4. (( <表达式> ))
    主要用于数值计算和比较,两端不需要空格
  5. 直接使用命令
    根据命令执行的成功(返回0)或失败(返回非0)来判断

6.1.1 test 条件测试示例

test 命令用于检查文件类型、比较值等。可以通过 help test 查看所有选项。

示例 1:检查文件是否存在

bash

[azurewhisky@shell ~]$ test -f file && echo true || echo false
  • 如果 file 存在(真),输出 true
  • 如果 file 不存在(假),输出 false
  • -f 测试是否为普通文件
  • && 表示“前一个命令成功就执行下一个”
  • || 表示“前一个命令失败就执行下一个”

也可以分开写:

bash

[azurewhisky@shell ~]$ test -f file && echo true  # 存在才输出
[azurewhisky@shell ~]$ test -f file || echo false # 不存在才输出

示例 2:检查变量是否为空

bash

[azurewhisky@shell ~]$ unset string        # 删除变量
[azurewhisky@shell ~]$ test -z "$string" && echo null string || echo $string
null string[azurewhisky@shell ~]$ string="hello world"
[azurewhisky@shell ~]$ test -z "$string" && echo null string || echo $string
hello world
  • -z 判断字符串长度是否为 0(空)
  • 注意:变量建议用双引号括起来,防止空变量导致语法错误

6.1.2 [] 条件测试示例

[]test 功能完全相同,只是写法不同。

示例:检查文件是否存在

bash

[azurewhisky@shell ~]$ [ -f file ] && echo true || echo false
  • 方括号 [ ] 内部两端必须有空格
  • 逻辑操作符 &&|| 两端加空格更清晰(可选但建议)

6.1.3 [[]] 条件测试示例

[[]] 是增强版测试命令,支持更强大的模式匹配。

示例:检查文件是否存在

bash

[azurewhisky@shell ~]$ [[ -f file ]] && echo true || echo false
  • 双括号 [[ ]] 内部两端也需要空格

提示test[][[]] 功能相似,选择一种你喜欢的即可(推荐 [])。


6.2 文件判断表达式

常用的文件测试选项:

选项全拼说明
-ddirectory存在且为目录则为真
-ffile存在且为普通文件则为真
-eexist存在则为真(不区分文件或目录)
-rread存在且可读则为真
-ssize存在且大小非0则为真
-wwrite存在且可写则为真
-xexecutable存在且可执行则为真
-Llink存在且为链接文件则为真
-ntnewer than文件1比文件2新则为真(按修改时间)
-otolder than文件1比文件2旧则为真(按修改时间)

示例:

bash

[azurewhisky@shell ~]$ data_path=/tmp/azurewhisky
[azurewhisky@shell ~]$ mkdir ${data_path}
[azurewhisky@shell ~]$ [ -d ${data_path} ] && echo "${data_path} exists"
/tmp/azurewhisky exists[azurewhisky@shell ~]$ rmdir ${data_path}
[azurewhisky@shell ~]$ [ -d ${data_path} ] || echo "${data_path} does not exist"
/tmp/azurewhisky does not exist# 检查是否可读 /etc/shadow(通常需要root权限)
[azurewhisky@shell ~]$ [ -r /etc/shadow ] && cat /etc/shadow || echo "Cannot read shadow file"
Cannot read shadow file# 如果 ~/.bashrc 可写,则追加别名
[azurewhisky@shell ~]$ [ -w ~/.bashrc ] && echo "alias pa='ps axu'" >> ~/.bashrc
[azurewhisky@shell ~]$ tail -1 ~/.bashrc
alias pa='ps axu'

多条命令的条件执行

如果条件成立后要执行多条命令,可以用 {} 组合:

bash

[ 条件 ] && {命令1命令2命令3
}

示例:

bash

[azurewhisky@shell ~]$ [ -w ~/.bashrc ] && {
> echo "alias sa='ssh root@servera'" >> ~/.bashrc
> echo "alias sb='ssh root@serverb'" >> ~/.bashrc
> echo "alias sc='ssh root@serverc'" >> ~/.bashrc
> }[azurewhisky@shell ~]$ tail -3 ~/.bashrc
alias sa='ssh root@servera'
alias sb='ssh root@serverb'
alias sc='ssh root@serverc'# 一行写多条命令(用分号分隔)
[azurewhisky@shell ~]$ [ -r /etc/passwd ] && { echo ha; echo ha; echo ha; }
ha
ha
ha

6.3 字符串判断表达式

常用字符串测试操作符:

表达式说明
-n "字符串"长度不为0则为真(非空)
-z "字符串"长度为0则为真(空)
"串1" = "串2"字符串相等则为真
"串1" != "串2"字符串不相等则为真

重要提示:

  • 字符串一定要用双引号括起来,避免空变量导致语法错误
  • 比较操作符(如 =两端必须有空格

示例 1:检查空字符串

bash

[azurewhisky@shell ~]$ unset string
[azurewhisky@shell ~]$ [ -z "$string" ] && echo "null string" || echo "$string"
null string[azurewhisky@shell ~]$ string="hello world"
[azurewhisky@shell ~]$ [ -z "$string" ] && echo "null string" || echo "$string"
hello world

示例 2:检查非空字符串

bash

[azurewhisky@shell ~]$ unset string
[azurewhisky@shell ~]$ [ -n "$string" ] && echo "$string" || echo "null string"
null string[azurewhisky@shell ~]$ string="hello world"
[azurewhisky@shell ~]$ [ -n "$string" ] && echo "$string" || echo "null string"
hello world

示例 3:字符串比较

bash

[azurewhisky@shell ~]$ string="hi"
[azurewhisky@shell ~]$ [ "$string" = "hi" ] && echo hi
hi
[azurewhisky@shell ~]$ [ "$string" = "ha" ] && echo ha  # 无输出[azurewhisky@shell ~]$ [ "$string" != "hi" ] && echo "not hi"  # 无输出
[azurewhisky@shell ~]$ [ "$string" != "ha" ] && echo "not ha"
not ha

实际应用案例

查看系统脚本中的条件判断:

bash

[azurewhisky@shell ~]$ sed -n '30,31p' /etc/init.d/network
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6

6.3.3 [[]] 中的模式匹配 =~

[[ ]] 支持使用 =~ 进行正则表达式匹配:

bash

[[ "$str" =~ pattern ]]

重要: =~ 右边的模式不要用引号,否则会被当作普通字符串而不是正则表达式。

示例:

bash

# 检查变量是否包含数字
[azurewhisky@shell ~]$ str=123abc
[azurewhisky@shell ~]$ [[ "$str" =~ [0-9]+ ]] && echo "Contains numbers" || echo "No numbers"
Contains numbers[azurewhisky@shell ~]$ str=abcdef
[azurewhisky@shell ~]$ [[ "$str" =~ [0-9]+ ]] && echo "Contains numbers" || echo "No numbers"
No numbers# 检查变量是否全是数字
[azurewhisky@shell ~]$ str=123
[azurewhisky@shell ~]$ [[ "$str" =~ ^[0-9]+$ ]] && echo "All numbers" || echo "Not all numbers"
All numbers# 错误示例:加引号后正则会失效
[azurewhisky@shell ~]$ str=123
[azurewhisky@shell ~]$ [[ "$str" =~ "[0-9]+" ]] && echo true || echo false 
false

6.4 整数比较操作符

两种风格的整数比较操作符:

在 [] 和 test 中在 [[]] 和 (()) 中说明
-eq===等于(equal)
-ne!=不等于(not equal)
-gt>大于(greater than)
-ge>=大于等于(greater equal)
-lt<小于(less than)
-le<=小于等于(less equal)

特别注意:

  • [] 中使用 >< 时需要转义(如 \>),否则可能被解释为重定向
  • 整数比较时,变量可以不加引号,但加上也不错

示例 1:使用 [] 比较

bash

[azurewhisky@shell ~]$ [ 2 -lt 3 ] && echo true || echo false
true
[azurewhisky@shell ~]$ [ 2 -gt 3 ] && echo true || echo false
false

示例 2:常见错误

bash

# 错误:> 不被转义时实际上是重定向,创建了名为 3 的文件!
[azurewhisky@shell ~]$ [ 2 > 3 ] && echo true
true# 正确:需要转义 >
[azurewhisky@shell ~]$ [ 2 \> 3 ] && echo true || echo false
false

示例 3:使用 [[]] 和 (()) 比较

bash

[azurewhisky@shell ~]$ a=98;b=99
[azurewhisky@shell ~]$ [[ $a = $b ]] && echo true || echo false
false[azurewhisky@shell ~]$ (( a >= b )) && echo true || echo false
false
[azurewhisky@shell ~]$ (( a <= b )) && echo true || echo false
true

小结:

  • [] 中用 -eq, -ne 等比较整数
  • [[]](()) 中用 ==, !=, >, < 等比较整数
  • [] 中使用 >< 需要转义

6.5 逻辑操作符

表达式内的逻辑操作符

在 [] 和 test 中在 [[]] 和 (()) 中说明
-a&&与(and)
-o``或(or)
!!非(not)

表达式外的逻辑操作符(连接命令)

  • &&:左边成功才执行右边
  • ||:左边失败才执行右边

示例:

bash

# 检查文件是否存在且可读
[azurewhisky@shell ~]$ file=/etc/passwd
[azurewhisky@shell ~]$ [ -f "$file" -a -r "$file" ] && head -1 "$file"
root:x:0:0:root:/root:/bin/bash# 使用 && 连接两个测试条件
[azurewhisky@shell ~]$ num=10
[azurewhisky@shell ~]$ [ "$num" -lt 20 -o "$num" -gt 1 ] && echo "$num is between 1 and 20"
10 is between 1 and 20# 使用 ! 取反
[azurewhisky@shell ~]$ [ ! 6 -eq 5 ] && echo "6 != 5"
6 != 5

实际应用案例

bash

# 如果目录不存在则创建
[azurewhisky@shell ~]$ data_path=/tmp/azurewhisky
[azurewhisky@shell ~]$ [ -d "$data_path" ] || mkdir "$data_path"
[azurewhisky@shell ~]$ ls -d "$data_path"
/tmp/azurewhisky

6.6 四种测试方法对比总结

特性说明[]test[[]](())
边界是否需要空格需要需要需要不需要
逻辑操作符!、-a、-o!、-a、-o!、&&、||!、&&、||
整数比较-eq、-ne、-gt等-eq、-ne、-gt等-eq、-ne、-gt等==、!=、>、<等
字符串比较=、==、!==、==、!==、==、!===、!=
通配符匹配不支持不支持支持(=~)不支持

建议:

  • 日常使用 [] 足够多数情况
  • 需要模式匹配时用 [[]]
  • 数值计算用 (())
  • 保持代码风格一致最重要

希望这份更轻松易懂的笔记能帮助你更好地学习和复习 Shell 条件测试!如有问题,欢迎随时提问。

http://www.xdnf.cn/news/18531.html

相关文章:

  • 一款更适合 SpringBoot 的API文档新选择(Spring Boot 应用 API 文档)
  • Rancher 管理的 K8S 集群中部署常见应用(MySQL、Redis、RabbitMQ)并支持扩缩容的操作
  • SpringBoot4发布!新特性解析
  • 2025.8.21总结
  • 【Bug】CentOS 7 使用vim命令报错vim: command not found
  • 37、需求预测与库存优化 (快消品) - /供应链管理组件/fmcg-inventory-optimization
  • AP状态管理中提到的两种“业务逻辑”
  • Java实现一个简单的LRU缓存对象
  • 50 C++ STL模板库-算法库 algorithm
  • python的校园研招网系统
  • RHCA10NUMA
  • Pytorch框架学习
  • Git 新手完全指南(一):从零开始掌握版本控制
  • 59. 螺旋矩阵 II|从“左闭右开”的圈层模拟入手(附图解与 C++ 实现)
  • 在 Linux 和 Docker 中部署 MinIO 对象存储
  • 使用Spring Retry组件优雅地实现重试
  • 【Python】利用heapq 模块实现一个按优先级排序的队列
  • 数字化图书管理系统设计实践(java)
  • CorrectNav——基于VLM构建带“自我纠正飞轮”的VLN:通过「视觉输入和语言指令」预测导航动作,且从动作和感知层面生成自我修正数据
  • 学习嵌入式的第二十二天——数据结构——双向链表
  • 永磁同步电机谐波抑制算法(13)——传统预测控制与传统谐波抑制的碰撞
  • week2-[二维数组]排队
  • MySQL 50 道经典练习题及答案
  • Java毕业设计选题推荐 |基于SpringBoot+Vue的知识产权管理系统设计与实现
  • Effective C++ 条款52:写了placement new也要写placement delete
  • ES常用查询命令
  • SQL详细语法教程(七)核心优化
  • ubuntu系统上的conda虚拟环境导出方便下次安装
  • PiscCode使用MediaPipe Face Landmarker实现实时人脸特征点检测
  • YOLO11 到 C++ 落地全流程:ONNX 导出、NMS 判别与推理实战