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

Shell 条件测试与 if 语句:从基础到实战

Shell 条件测试与 if 语句:从基础到实战

在这里插入图片描述

在 Shell 脚本中,条件测试和 if 语句是实现逻辑判断的核心工具,能够根据不同情况执行不同命令。本文详细讲解条件测试的类型、表达式及 if 语句的用法,并通过实战案例巩固知识点。

一、条件测试类型

条件测试用于判断“整数大小”“字符串是否相等”“文件是否存在”等场景,主要分为三类:

测试类型作用范围核心运算符/选项
整数测试比较两个整数的大小(相等、大于、小于等)-eq(等于)、-gt(大于)、-lt(小于)等
字符测试检查字符串是否为空、是否相等==(相等)、-z(空字符串)、-n(非空字符串)
文件测试判断文件/目录的属性(存在性、类型、权限等)-e(存在)、-f(普通文件)、-d(目录)等

二、条件测试的表达式

Shell 提供三种方式编写条件测试表达式,效果相同,可根据习惯选择:

表达式格式语法示例说明
test 条件test $a -gt $b最原始的测试命令,兼容性好。
[ 条件 ][ $a -gt $b ]简化写法,[ 后和 ] 前必须有空格。
[[ 条件 ]][[ $a -gt $b ]]Bash 扩展语法,支持模式匹配,推荐使用。

示例:测试文件是否存在

# 创建测试文件
[root@ansible ~]# touch file.txt# 三种方式测试文件是否存在
[root@ansible ~]# test -e file.txt && echo "存在" || echo "不存在"  
存在
[root@ansible ~]# [ -e file.txt ] && echo "存在" || echo "不存在"  
存在
[root@ansible ~]# [[ -e file.txt ]] && echo "存在" || echo "不存在" 
存在# 测试不存在的文件
[root@ansible ~]# [[ -e nofile.txt ]] && echo "存在" || echo "不存在" 
不存在

说明:&& 表示“条件为真时执行后面命令”,|| 表示“条件为假时执行后面命令”,常用于简化判断逻辑。

三、整数测试

用于比较两个整数的关系,核心运算符如下:

运算符含义示例(a=10b=5结果
-eq等于[[ $a -eq $b ]]假(10≠5)
-ne不等于[[ $a -ne $b ]]真(10≠5)
-gt大于[[ $a -gt $b ]]真(10>5)
-lt小于[[ $a -lt $b ]]假(10<5)
-ge大于或等于[[ $a -ge 10 ]]真(10≥10)
-le小于或等于[[ $b -le 5 ]]真(5≤5)

实战案例:整数比较脚本

需求:接收两个参数,判断是否为整数并比较大小。

#!/bin/bash
# 脚本名:compare_num.sh
# 功能:比较两个整数的大小# 1. 检查参数数量(必须输入2个参数)
if [ $# -ne 2 ]; thenecho "错误:必须输入两个参数!"exit 1  # 非0退出表示执行失败
fi# 2. 检查参数是否为整数(通过expr计算是否报错)
expr $1 + $2 > /dev/null 2>&1  # 重定向所有输出到黑洞(不显示错误)
if [ $? -ne 0 ]; then  # $? 为上一条命令的返回码,非0表示不是整数echo "错误:输入的参数必须是整数!"exit 1
fi# 3. 比较两个整数大小
num1=$1
num2=$2if [ $num1 -gt $num2 ]; thenecho "$num1 大于 $num2"
elif [ $num1 -eq $num2 ]; thenecho "$num1 等于 $num2"
elseecho "$num1 小于 $num2"
fi
执行测试
[root@ansible ~]#  sh test1.sh 10 5
10 大于 5
[root@ansible ~]#  sh test1.sh 5 5
5 等于 5
[root@ansible ~]#  sh test1.sh 2 8
2 小于 8
[root@ansible ~]#  sh test1.sh 1
错误:必须输入两个参数!
[root@ansible ~]#  sh test1.sh a b
错误:输入的参数必须是整数!

四、字符测试

用于处理字符串相关的判断,核心运算符如下:

运算符含义示例(str1="abc"str2="def"结果
==字符串相等(= 也可,推荐 ==[[ $str1 == $str2 ]]假(abc≠def)
!=字符串不相等[[ $str1 != $str2 ]]真(abc≠def)
-z "字符串"字符串为空(长度为0)[[ -z "" ]]真(空字符串)
-n "字符串"字符串非空(长度≥1)[[ -n $str1 ]]真(abc非空)

示例:字符测试脚本

[root@ansible ~]# vim test2.sh#!/bin/bash
# 脚本名:string_test.shstr1="hello"
str2="world"
empty_str=""# 测试字符串是否相等
if [[ $str1 == $str2 ]]; thenecho "$str1$str2 相等"
elseecho "$str1$str2 不相等"  # 输出此结果
fi# 测试字符串是否为空
if [[ -z $empty_str ]]; thenecho "empty_str 是空字符串"  # 输出此结果
elseecho "empty_str 不是空字符串"
fi# 测试字符串是否非空
if [[ -n $str1 ]]; thenecho "$str1 不是空字符串"  # 输出此结果
elseecho "$str1 是空字符串"
fi执行脚本:
[root@ansible ~]# chmod +x test2.sh
[root@ansible ~]# ./test2.sh 
hello 和 world 不相等
empty_str 是空字符串
hello 不是空字符串

五、文件测试

用于检查文件/目录的属性,是运维脚本中最常用的测试类型,核心选项如下:

选项含义示例(file="/tmp/test.txt"
-e 文件文件是否存在[[ -e $file ]]
-f 文件是否为普通文件(非目录/设备)[[ -f $file ]]
-d 目录是否为目录[[ -d /tmp ]]
-L 文件是否为符号链接文件[[ -L /tmp/link ]]
-r 文件当前用户是否有读权限[[ -r $file ]]
-w 文件当前用户是否有写权限[[ -w $file ]]
-x 文件当前用户是否有执行权限[[ -x /bin/ls ]]
-s 文件文件是否非空(大小>0)[[ -s $file ]]
文件1 -nt 文件2文件1是否比文件2新(修改时间更新)[[ /tmp/a -nt /tmp/b ]]

实战案例:文件属性检查脚本

[root@ansible ~]# vim test3.sh#!/bin/bash
# 脚本名:file_check.sh
# 功能:检查指定文件的属性# 接收用户输入的文件路径
read -p "请输入要检查的文件路径:" file# 1. 检查文件是否存在
if [[ ! -e $file ]]; then  # ! 表示取反echo "错误:文件 $file 不存在!"exit 1
fi# 2. 检查文件类型
if [[ -f $file ]]; thentype="普通文件"
elif [[ -d $file ]]; thentype="目录"
elif [[ -L $file ]]; thentype="符号链接"
elsetype="其他类型文件"
fi# 3. 检查权限
perm=""
[[ -r $file ]] && perm+="读"
[[ -w $file ]] && perm+="写"
[[ -x $file ]] && perm+="执行"# 4. 输出结果
echo "文件 $file 的属性:"
echo "类型:$type"
echo "权限:$perm"
echo "是否非空:$( [[ -s $file ]] && echo "是" || echo "否" )"
执行测试
[root@ansible ~]# chmod +x test3.sh# 测试普通文件
[root@ansible ~]# ./test3.sh 
请输入要检查的文件路径:file
文件 file 的属性:
类型:普通文件
权限:读写
是否非空:否# 测试目录
[root@ansible ~]# ./test3.sh 
请输入要检查的文件路径:/tmp
文件 /tmp 的属性:
类型:目录
权限:读写执行
是否非空:是

六、组合测试

通过逻辑运算符组合多个条件,实现复杂判断,常用逻辑运算符:

运算符含义等价符号示例(判断 a 是 1-10 之间的整数)
-a逻辑与&&[[ $a -ge 1 -a $a -le 10 ]][[ $a -ge 1 && $a -le 10 ]]
-o逻辑或`
!逻辑非![[ ! -e $file ]](文件不存在)

示例:组合条件判断

#!/bin/bash
# 检查参数是否为 1-10 之间的整数
read -p "请输入一个数字:" num# 组合条件:是整数 且 大于等于1 且 小于等于10
if [[ $num =~ ^[0-9]+$ && $num -ge 1 && $num -le 10 ]]; thenecho "$num 是 1-10 之间的整数"
elseecho "$num 不是 1-10 之间的整数"
fi

七、if 语句

if 语句根据条件测试的结果(真/假)执行不同的命令块,分为单分支、双分支和多分支三种结构。

1. 单分支 if 语句

语法

if 条件测试; then条件为真时执行的命令
fi

案例:判断当前用户是否为 root

[root@ansible ~]# vim aa.sh#!/bin/bash
# 脚本名:check_root.shif [[ $USER != "root" ]]; thenecho "错误:必须以 root 用户执行此脚本!"exit 1
fiecho "欢迎,root 用户!"执行脚本:
[root@ansible ~]# sh aa.sh 
欢迎,root 用户!

2. 双分支 if 语句

语法

if 条件测试; then条件为真时执行的命令
else条件为假时执行的命令
fi

案例:判断文件是否存在,不存在则创建

[root@ansible ~]# vim bb.sh#!/bin/bash
# 脚本名:create_file.shfile="/tmp/auto_create.txt"if [[ -e $file ]]; thenecho "文件 $file 已存在"
elseecho "文件 $file 不存在,正在创建..."touch $fileecho "创建成功!"
fi执行脚本:
[root@ansible ~]# sh bb.sh 
文件 /tmp/auto_create.txt 不存在,正在创建...
创建成功!
[root@ansible ~]# sh bb.sh 
文件 /tmp/auto_create.txt 已存在
[root@ansible ~]# 

3. 多分支 if 语句

语法

if 条件1; then条件1为真时执行的命令
elif 条件2; then条件2为真时执行的命令
elif 条件3; then条件3为真时执行的命令
else所有条件都为假时执行的命令
fi

案例:根据分数评级(90-100 为 A,80-89 为 B,否则为 C)

[root@ansible ~]# vim cc.sh#!/bin/bash
# 脚本名:grade.shread -p "请输入分数(0-100):" score# 检查是否为合法分数
if ! [[ $score =~ ^[0-9]+$ && $score -ge 0 && $score -le 100 ]]; thenecho "错误:请输入 0-100 之间的整数!"exit 1
fi# 评级
if [[ $score -ge 90 ]]; thengrade="A"
elif [[ $score -ge 80 ]]; thengrade="B"
elsegrade="C"
fiecho "你的评级是:$grade"执行脚本:
[root@ansible ~]# sh cc.sh 
请输入分数(0-100):101
错误:请输入 0-100 之间的整数!
[root@ansible ~]# sh cc.sh 
请输入分数(0-100):80
你的评级是:B
[root@ansible ~]# sh cc.sh 
请输入分数(0-100):90
你的评级是:A
[root@ansible ~]# sh cc.sh 
请输入分数(0-100):60
你的评级是:C

总结

条件测试和 if 语句是 Shell 脚本实现逻辑控制的基础,核心要点:

  1. 测试类型:整数、字符串、文件测试覆盖了绝大多数判断场景;
  2. 表达式格式:推荐使用 [[ 条件 ]],兼容性好且支持扩展功能;
  3. if 结构:根据需求选择单分支(简单判断)、双分支(二选一)或多分支(多选一);
  4. 实战技巧:结合逻辑运算符(&&/||/!)实现复杂条件,用 $? 检查命令执行结果。

掌握这些内容后,可编写具有复杂逻辑的自动化脚本,如系统监控、文件管理、批量部署等。


文章转载自:

http://m3nudQui.jydhL.cn
http://Sm6EKMfo.jydhL.cn
http://5n0kWkG5.jydhL.cn
http://ZMI6mvxZ.jydhL.cn
http://di4gS1Ns.jydhL.cn
http://QmxSrANK.jydhL.cn
http://UtWYP18i.jydhL.cn
http://Srituwkd.jydhL.cn
http://arabSSqZ.jydhL.cn
http://LeEPt0Ji.jydhL.cn
http://oLKblwZA.jydhL.cn
http://t3qKvgek.jydhL.cn
http://UKmYbkLZ.jydhL.cn
http://9SvRZtWI.jydhL.cn
http://4gLSrfSJ.jydhL.cn
http://wea6a7Il.jydhL.cn
http://TaqPbxHe.jydhL.cn
http://w788ixY7.jydhL.cn
http://WBX0Nid8.jydhL.cn
http://m4Euc6fg.jydhL.cn
http://LRvmRAjO.jydhL.cn
http://nVl3WryZ.jydhL.cn
http://PXmGPU0l.jydhL.cn
http://KfN8RxNd.jydhL.cn
http://UHWd8cHS.jydhL.cn
http://LYTKYqMc.jydhL.cn
http://SYINgLbr.jydhL.cn
http://SfOwwXcn.jydhL.cn
http://kUNBMzF9.jydhL.cn
http://FfksLmc4.jydhL.cn
http://www.dtcms.com/a/376961.html

相关文章:

  • 数据结构 之 【布隆过滤器 的简介】
  • 《sklearn机器学习——数据预处理》归一化
  • 网络编程(7)
  • 嘉立创EDA从原理图框选住器件进行PCB布局
  • 浅谈代理流程自动化 (APA)
  • 图论3 图的遍历
  • MySQL内核革新:智能拦截全表扫描,百度智能云守护数据库性能与安全
  • 从0°到180°,STM32玩转MG996R舵机
  • Openresty Tracing 最佳实践
  • 少儿舞蹈小程序(12)作品列表查询搭建
  • 机器学习投票分类
  • Python Web工程之Flask项目中添加健康检查
  • javaEE-Spring IOCDI
  • 《常见关键字知识整理》
  • C++中的单例模式的实现
  • 淘宝闪购基于FlinkPaimon的Lakehouse生产实践:从实时数仓到湖仓一体化的演进之路
  • 云手机怎样进行自动化运行?
  • FPGA入门-状态机
  • 【Python Tkinter 】图形用户界面(GUI)开发及打包EXE指南
  • 工作效率翻倍!Excel多文件合并工具
  • 【Pywinauto库】8.4 pywinauto.timings模块
  • 4.7 静态分支, 动态分支和变体
  • LangGraph中ReAct模式的深度解析:推理与行动的完美融合——从理论到实践的智能Agent构建指南
  • 【机械故障】使用fir滤波器实现数据拟合
  • vue3 中 npm install mammoth 与 npm install --save mammoth 的主要区别说明
  • Milvus基于docker主机外挂实践
  • 从零搭建企业级日志系统:Web + App 全端解决方案实战!
  • 【算法--链表】138.随机链表的复制--通俗讲解
  • Nodejs(③Stream)
  • iOS 26支持的设备列表