关于shell脚本if语句详解

引言

论Shell脚本中条件判断的重要性:作为自动化运维的核心组件,条件判断直接影响脚本的健壮性和容错能力。据统计,75%的脚本错误源于条件逻辑缺陷。

if语句在Shell编程中的核心地位:if语句占据Shell脚本30%-50%的代码量,其性能优化可提升整体执行效率20%以上(基于Linux内核测试数据)。

一、if 语句底层逻辑

条件判断的本质:布尔运算的Shell实现
三大应用场景:文件操作/数值比较/流程控制
常见误区:条件表达式与Shell语法的差异

二、if 语句语法精讲

2.1、基本语法结构

2.1.1 单分支if语句

if [ 判断条件 ]; then
     满足“判断条件”后执行的指令
fi
或者
if [ 判断条件 ]
then
     满足“判断条件”后执行的指令
fi

2.1.2 双分支if语句

if [ 判断条件 ]; then
     符合“判断条件”后执行的指令
else
     不符合“判断条件”执行的指令
fi

2.1.3 多分支if-elif-else语句

if [ 判断条件1 ]; then
     符合“判断条件1”后执行的指令
elif [ 判断条件2 ]; then
     符合“判断条件2”后执行的指令
else
     不符合“判断条件1”又不符合“判断条件2”执行的指令
fi

    ---- 更多的判断分支也以此类推来继续增加

2.2、文件/目录类判断

常用类:
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。

不常用类型:
[ -b FILE ] 如果 FILE 存在且是一个块文件则返回为真。
[ -c FILE ] 如果 FILE 存在且是一个字符文件则返回为真。
[ -g FILE ] 如果 FILE 存在且设置了SGID则返回为真。
[ -h FILE ] 如果 FILE 存在且是一个符号符号链接文件则返回为真。(该选项在一些老系统上无效)
[ -k FILE ] 如果 FILE 存在且已经设置了冒险位则返回为真。
[ -p FILE ] 如果 FILE 存并且是命令管道时返回为真。
[ -s FILE ] 如果 FILE 存在且大小非0时为真则返回为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID位时返回为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则返回为真。
[ -G FILE ] 如果 FILE 存在且默认组为当前组则返回为真。(只检查系统默认组)
[ -L FILE ] 如果 FILE 存在且是一个符号连接则返回为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则返回为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则返回为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新, 或者 FILE1 存在但是 FILE2 不存在则返回为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 老, 或者 FILE2 存在但是 FILE1 不存在则返回为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则返回为真。

2.3、字符串类判断

[ -z STRING ] 如果STRING的长度为零则返回为真,即空是真
[ -n STRING ] 如果STRING的长度非零则返回为真,即非空是真
[ STRING1 ]  如果字符串不为空则返回为真,与-n类似
[ STRING1 == STRING2 ] 如果两个字符串相同则返回为真
[ STRING1 != STRING2 ] 如果字符串不相同则返回为真
[ STRING1 < STRING2 ] 如果 “STRING1”字典排序在“STRING2”前面则返回为真。
[ STRING1 > STRING2 ] 如果 “STRING1”字典排序在“STRING2”后面则返回为真。

2.4、数值类判断

[ INT1 -eq INT2 ] INT1和INT2两数相等返回为真 ,=
[ INT1 -ne INT2 ] INT1和INT2两数不等返回为真 ,<>
[ INT1 -gt INT2 ] INT1大于INT2返回为真 ,>
[ INT1 -ge INT2 ] INT1大于等于INT2返回为真,>=
[ INT1 -lt INT2 ] INT1小于INT2返回为真 ,<
[ INT1 -le INT2 ] INT1小于等于INT2返回为真,<=

2.5、逻辑类判断

[ ! EXPR ] 逻辑非,如果 EXPR 是false则返回为真。
[ EXPR1 -a EXPR2 ] 逻辑与,如果 EXPR1 and EXPR2 全真则返回为真。
[ EXPR1 -o EXPR2 ] 逻辑或,如果 EXPR1 或者 EXPR2 为真则返回为真。
[ ] || [ ] 用OR来合并两个条件
[ ] && [ ] 用AND来合并两个条件
[[  &&  ]][[ AND ]]来合并两个条件

三、表达式边界规则

表达式符号test中括号 [ ]双中括号 [[ ]]双小括号 (( ))
符号边界两边有空格两边有空格两边有空格可有可无
逻辑操作! 、-a 、-o! 、-a 、-o! 、&&、||! 、&&、||
整数比较-eq,-gt,-lt,-ge,-le-eq,-gt,-lt,-ge,-le-eq,-gt,-lt,-ge,-le或=,>,<,>=,<=,!==,>,<,>=,<=,!=
字符串比较=、==、!==、==、!==、==、!==、==、!=
正则和通配符不支持不支持支持不支持

注意 注意:

中括号 [ ]:是一个标准的 Unix 命令,也被称为 test。它在所有 POSIX shell 中都可用,包括 sh、bash、ksh、dash 等。

双中括号 [[ ]] :是 bash 和其他一些现代 shell(如 zsh 和 ksh)中的关键字,提供了比 [ 更强大的功能。例如,它支持字符串模式匹配和正则表达式匹配

在shell中,= 和 == 运算符都可以用于判断两个字符串、两个字符串变量是否相同,== 支持模式匹配,但 = 不支持模式匹配。

四、执行流程详解

4.1、条件检测阶段‌
解析 <判断条件> 或test <判断条件> 表达式
检查文件状态(-e/-f)、数值比较(-eq/-gt)或字符串匹配(=/-z)
返回状态码:0(真)或非0(假)

‌4.2、分支跳转逻辑‌
若首条件为真 → 执行then块 → 跳过后续elif/else直接到fi
若首条件为假 → 依次检查后续elif条件 → 所有条件均假时执行else块
嵌套if时,外层判断通过后才进入内层条件检测

4.3、边界处理特性‌
空else分支必须删除(与PHP等语言不同)
方括号与条件间必须保留空格,否则语法错误

五、案例详解

5.1、文件/目录判断案例

# 判断文件/目录是否存在 
if [ -e "file" ]; then      
    echo "File exists" 
else
    echo "File does not exist"
fi

5.2、字符串判断案例

if [ "$var1" == "$var2" ]; then
  echo '$var1 eq $var2'
else
  echo '$var1 not eq $var2'
fi

5.3、数值判断案例

if [ "$num" -gt "150" ];then
   echo "$num is biger than 150"
fi

5.4、逻辑判断案例

if [[ "var1" = "var1" && "var2" = "var2" ]]
then 
    echo "True"
else
    echo "False"
fi

5.5、通配符匹配和正则表达式匹配案例

# 通配符匹配
if [[ "${Var}" == value* ]]; then
    echo "The Var is with 'value'"
fi
# 正则表达式匹配
if [[ "${Var}" =~ ^value ]]; then
    echo "The Var is with 'value'"
fi

六、通用建议

‌空格规则‌: 括号内的括号与表达式之间必须保留空格,否则报语法错误
‌条件顺序‌:多条件时按逻辑顺序排列(升序/降序),避免遗漏
‌变量引用‌:建议用${var}形式避免歧义,未定义变量会导致条件异常
‌引号使用‌:含空格的字符串需加引号,如if [ “$str” = “hello” ]
‌复合语句‌:即使单行也建议使用大括号/缩进,增强可读性
验证结果:通过echo $?验证最后执行的命令返回值
‌布尔简化‌:避免冗余条件(如if (x == true)可直接写为if (x))
推荐使用‌:复杂条件建议使用双中括号 [[ ]] 避免单词分割问题

参考原文链接:https://blog.csdn.net/zzddada/article/details/120722480

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值