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

【Shell 脚本编程】详细指南:第三章 - 运算符与条件判断

Shell 脚本编程详细指南:第三章 - 运算符与条件判断完全指南

引言:掌握Shell逻辑控制的核心

条件判断是Shell脚本实现复杂逻辑的基石。本章将深入解析各种运算符和条件判断结构,帮助您编写更健壮、更高效的脚本。我们将从基础语法入手,逐步探讨高级用法和最佳实践。

1. 数值运算的全面解析

1.1 五种数值计算方法对比

方法示例优点缺点
$(( ))echo $((a * b))高效,语法简洁 ,最常用Bash特有
exprexpr $a + $bPOSIX兼容性能差,需要转义特殊字符
letlet sum=a+b可直接修改变量可读性较差
bcecho "5.2+3.8" | bc支持浮点数运算需要外部命令
awkawk "BEGIN{print $a/$b}"高精度计算语法复杂

1.2 实际运算示例

整数运算:

a=15 b=4
echo "加法: $((a + b))"        # 19
echo "取模: $((a % b))"       # 3
echo "幂运算: $((a ** 2))"    # 225

浮点运算(使用bc):

pi=$(echo "scale=10; 4*a(1)" | bc -l)  # 计算π值
echo "圆周率: $pi"  # 3.1415926535

位运算:

flags=5
echo "二进制: $((flags>>1))"  # 2 (0101 → 0010)

2. 比较运算符深度剖析

2.1 数值比较运算符表

运算符含义等价数学符号
-eq等于==
-ne不等于!=
-gt大于>
-ge大于等于>=
-lt小于<
-le小于等于<=

2.2 字符串比较运算符表

运算符含义示例
=相等[ "$str" = "test" ]
!=不相等[[ "$str" != "" ]]
< >ASCII比较(需在[[ ]]中使用)[[ "a" < "b" ]]
=~正则匹配(Bash扩展)[[ "$str" =~ ^[0-9]+$ ]]
-z空字符串[ -z "$var" ]
-n非空字符串[ -n "$var" ]

2.3 文件测试运算符

[ -e file ]    # 存在
[ -f file ]    # 是普通文件
[ -d file ]    # 是目录
[ -r file ]    # 可读
[ -w file ]    # 可写
[ -x file ]    # 可执行
[ -s file ]    # 大小>0
[ file1 -nt file2 ]  # file1比file2新

3. 条件判断结构详解

3.1 if语句的四种形式

基本形式:

if [ condition ]; thencommands
fi

if-else:

if [[ $num -gt 10 ]]; thenecho "大于10"
elseecho "小于等于10"
fi

if-elif-else:

if [ "$score" -ge 90 ]; thengrade="A"
elif [ "$score" -ge 80 ]; thengrade="B"
elsegrade="C"
fi

嵌套if:

if [ -f "$file" ]; thenif [ -s "$file" ]; thenecho "文件存在且非空"fi
fi

3.2 条件连接运算符

运算符含义示例
&&逻辑与[ $a -gt 0 ] && [ $a -lt 10 ]
||逻辑或`[ -z “$str” ]
!逻辑非if ! [ -d "$dir" ]; then

4. 测试表达式进阶技巧

4.1 [ ] vs [[ ]] 对比

特性[ ] (test)[[ ]] (Bash扩展)
字符串比较支持支持(更安全)
模式匹配不支持支持(=~)
逻辑运算-a/-o&&/||
单词分割会发生不会发生
文件通配会展开不会展开

推荐实践:

# 使用[[ ]]避免变量引用问题
if [[ "$filename" == *.log ]]; thenecho "日志文件"
fi

4.2 正则表达式匹配

read -p "输入邮箱地址: " email
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; thenecho "有效邮箱"
elseecho "无效邮箱格式"
fi

5. 实战案例与解决方案

案例1:计算器脚本

#!/bin/bash
# calculator.shif [[ $# -ne 3 ]]; thenecho "用法: $0 数字 运算符 数字"echo "示例: $0 5 + 3"exit 1
ficase $2 in+) result=$(($1 + $3)) ;;-) result=$(($1 - $3)) ;;*) result=$(($1 * $3)) ;;/) [[ $3 -eq 0 ]] && { echo "错误: 除数不能为0"; exit 1; }result=$(echo "scale=2; $1 / $3" | bc) ;;%) result=$(($1 % $3)) ;;^) result=$(($1 ** $3)) ;;*) echo "不支持的操作符: $2"; exit 1 ;;
esacecho "结果: $result"

案例2:文件备份脚本

#!/bin/bash
# backup.shread -p "输入要备份的文件路径: " filepathif [[ ! -e "$filepath" ]]; thenecho "错误: 文件不存在" >&2exit 1
elif [[ ! -r "$filepath" ]]; thenecho "错误: 文件不可读" >&2exit 1
fibackup_dir="${HOME}/backups"
mkdir -p "$backup_dir"timestamp=$(date +%Y%m%d_%H%M%S)
filename=$(basename "$filepath")
backup_file="${backup_dir}/${filename}.${timestamp}.bak"if cp "$filepath" "$backup_file"; thenecho "备份成功: $backup_file"
elseecho "备份失败" >&2exit 1
fi

6. 最佳实践与常见陷阱

6.1 必须遵循的规范

  1. 变量引用:

    # 正确
    if [ "$var" -gt 0 ]; then# 危险
    if [ $var -gt 0 ]; then
    
  2. 字符串比较:

    # 使用双中括号避免分词
    if [[ "$str" == "value" ]]; then
    
  3. 数值比较:

    # 使用双括号进行算术比较
    if ((num > max)); then
    

6.2 常见错误排查

问题1:未引用的变量导致语法错误

# 错误
if [ $var = "test" ]; then  # 当$var为空时变成 [ = "test" ]# 正确
if [ "$var" = "test" ]; then

问题2:使用错误的比较运算符

# 错误:在[ ]中使用>进行字符串比较
if [ "$str1" > "$str2" ]; then# 正确
if [[ "$str1" > "$str2" ]]; then

进阶技巧

多条件测试优化

# 传统方式(创建子进程)
if [ "$a" -gt 0 ] && [ "$a" -lt 10 ]; then# 高效方式(Bash内置)
if [[ "$a" -gt 0 && "$a" -lt 10 ]]; then

使用算术表达式

# 在条件中直接计算
if (( (a + b) > (c * 2) )); thenecho "条件满足"
fi

本章总结

本章深入探讨了Shell脚本中的运算符和条件判断,重点包括:

  • 五种数值运算方法的对比与选择
  • 全面的比较运算符参考表
  • 条件判断结构的各种形式与应用场景
  • [ ]与[[ ]]的深度对比与选择建议
  • 实际案例分析和最佳实践

🔍 下章预告:第四章将深入讲解循环结构(for/while/until)和流程控制(case/select),带您掌握Shell脚本的自动化处理能力。

互动练习:
编写一个脚本,实现以下功能:

  1. 检查/tmp目录是否存在
  2. 如果存在,统计其中的文件数量
  3. 根据文件数量输出不同消息:
    • 空目录:0-5个文件
    • 正常:6-20个文件
    • 过多:20+个文件

欢迎在评论区分享您的实现方案!

相关文章:

  • PostgreSQL:pgAdmin 4 使用教程
  • tiktok web X-Bogus X-Gnarly 分析
  • 【dify—8】Agent实战——占星师
  • L3-041 影响力
  • 艺华直播 5.0 |专注于提供港澳台及央视频道的电视直播应用,加载快,播放流畅
  • PMP-第九章 项目资源管理(一)
  • 嵌入式产品运行中数据丢失怎么办?
  • ES6异步编程中Promise与Proxy对象
  • centos7 离线安装python3 保留python2
  • 使用Set和Map解题思路
  • 25.4.30数据结构|并查集 路径压缩
  • 企业经营系统分类及功能详解
  • Java状态机实战:打造高扩展性的订单流程引擎(含源码详解与快照设计)
  • Memory Bank 不够用?Cline 全新 CRCT:省 token,依赖关系自行追踪
  • OpenGL-ES 学习(13) ---- Shader 编译和程序对象
  • 生产级RAG系统一些经验总结
  • 构建强大垂直领域AI数据能力
  • C++11新特性_自动类型推导_decltype
  • 第3篇:请求参数处理与数据校验
  • Narendra自适应控制器设计
  • 云南石屏举办茶文化交流活动:弘扬企业家精神,激发市场活力
  • 八成盈利,2024年沪市主板公司实现净利润4.35万亿元
  • 日菲同意扩大安全合作,外交部:反对任何在本地区拉帮结派的做法
  • 广东省副省长刘红兵跨省调任湖南省委常委、宣传部长
  • 广西干旱程度有所缓解,未来一周旱情偏重地区降水量仍不足
  • 杜前任宁波中院代理院长,卸任宁波海事法院院长