五十、【Linux系统shell脚本】case语句 、 函数及中断控制演示
case语句、函数及中断控制
- 一、case 多分支语句
- 类型匹配对比
- 1. 服务管理脚本
- 2. 文件类型识别
- 二、函数封装
- 函数特性对比
- 函数作用域规则
- 1. 基础函数定义
- 2. 函数返回值
- 三、中断控制
- 1. break 与 continue
- 2. exit 与 trap
- 命令总结表格
- 功能作用详解
- 1. case 语句详解
- 2. 函数高级技巧
- 3. 中断控制场景
- 4. 生产级脚本模板
- 综合案例:菜单交互系统
一、case 多分支语句
类型匹配对比
匹配类型 | 语法示例 | 匹配规则 | 适用场景 | 注意事项 |
---|---|---|---|---|
固定字符串 | "start" | 精确匹配 | 命令参数处理 | 区分大小写 |
通配符模式 | "*.log" | 文件扩展名匹配 | 文件类型处理 | 需引号包裹 |
字符组 | [Yy] | 匹配指定字符 | 用户输入处理 | 不支持范围 |
或连接 | `“stop” | “halt”` | 多条件匹配 | 同义命令处理 |
正则表达式 | ^[0-9]+$ | Bash扩展正则 | 复杂模式匹配 | 需=~ 操作符 |
1. 服务管理脚本
# 创建服务控制脚本
[root@localhost ~]# vi service_ctl.sh
#!/bin/bash
service=$1
action=$2case "$action" instart)systemctl start $serviceecho "$service 已启动";;stop)systemctl stop $serviceecho "$service 已停止";;restart)systemctl restart $serviceecho "$service 已重启";;status)systemctl status $service --no-pager;;*)echo "用法: $0 <服务名> {start|stop|restart|status}"exit 1;;
esac# 测试执行
[root@localhost ~]# chmod +x service_ctl.sh
[root@localhost ~]# ./service_ctl.sh nginx start
nginx 已启动
2. 文件类型识别
# 创建文件类型检测脚本
[root@localhost ~]# vi file_type.sh
#!/bin/bash
read -p "输入文件路径: " filecase $(file -b "$file") in*"ELF"*)echo "可执行程序" ;;*"text"*)echo "文本文件" ;;*"directory"*)echo "目录" ;;*"JPEG"*)echo "JPEG图片" ;;*)echo "未知类型" ;;
esac# 测试执行
[root@localhost ~]# ./file_type.sh
输入文件路径: /bin/bash
可执行程序
二、函数封装
函数特性对比
特性 | 语法 | 作用域 | 返回值 | 最佳实践 |
---|---|---|---|---|
定义 | func() { ... } | 当前Shell | 状态码(0-255) | 使用小写命名 |
参数 | $1,$2,... | 函数局部 | 通过位置传递 | 最多9个参数 |
局部变量 | local var | 函数内部 | 不污染全局 | 必须声明 |
返回值 | return N | 调用环境 | $? 获取 | 0成功非0失败 |
输出捕获 | var=$(func) | 子Shell | 标准输出 | 避免副作用 |
函数作用域规则
1. 基础函数定义
# 创建计算器函数
[root@localhost ~]# vi math_functions.sh
#!/bin/bash
# 加法函数
add() {echo "$1 + $2 = $(($1 + $2))"
}# 减法函数
sub() {echo "$1 - $2 = $(($1 - $2))"
}# 调用函数
add 15 7 # 15 + 7 = 22
sub 20 5 # 20 - 5 = 15# 执行结果
[root@localhost ~]# ./math_functions.sh
15 + 7 = 22
20 - 5 = 15
2. 函数返回值
# 创建用户检查函数
[root@localhost ~]# vi user_check.sh
#!/bin/bash
# 检查用户是否存在
user_exists() {id "$1" &>/dev/nullreturn $? # 返回上条命令状态码
}# 使用函数
if user_exists "nginx"; thenecho "nginx 用户存在"
elseecho "nginx 用户不存在"
fi# 测试执行
[root@localhost ~]# ./user_check.sh
nginx 用户存在
三、中断控制
1. break 与 continue
# 创建循环控制脚本
[root@localhost ~]# vi loop_control.sh
#!/bin/bash
# break 示例:找到第一个大于5的数
echo "break 示例:"
for i in {1..10}; doif [ $i -gt 5 ]; thenecho "找到 $i > 5,终止循环"breakfiecho $i
done# continue 示例:跳过偶数
echo "continue 示例:"
for i in {1..10}; doif [ $((i % 2)) -eq 0 ]; thencontinue # 跳过本次迭代fiecho "奇数: $i"
done# 执行结果
[root@localhost ~]# ./loop_control.sh
break 示例:
1
2
3
4
5
找到 6 > 5,终止循环
continue 示例:
奇数: 1
奇数: 3
奇数: 5
奇数: 7
奇数: 9
2. exit 与 trap
# 创建中断处理脚本
[root@localhost ~]# vi trap_example.sh
#!/bin/bash
# 定义清理函数
cleanup() {echo "捕获中断,正在清理临时文件..."rm -f /tmp/temp_*.tmpexit 1 # 退出脚本
}# 注册信号捕获
trap cleanup SIGINT SIGTERM# 创建临时文件
touch /tmp/temp_1.tmp
echo "按 Ctrl+C 测试中断处理"# 模拟长时间运行
sleep 30
echo "正常结束"# 测试:执行后按 Ctrl+C
[root@localhost ~]# ./trap_example.sh
按 Ctrl+C 测试中断处理
^C捕获中断,正在清理临时文件...
命令总结表格
演示命令 | 功能描述 | 关键语法/参数 |
---|---|---|
case $var in ... esac | 多分支匹配 | pattern) 匹配模式, ;; 结束分支 |
function_name() { ... } | 定义函数 | 大括号内写函数体 |
return N | 函数返回值 | $? 获取返回值 |
break | 终止循环 | 跳出当前循环体 |
continue | 跳过本次迭代 | 继续下一轮循环 |
exit N | 退出脚本 | N 为退出状态码 |
trap '命令' 信号 | 信号捕获 | SIGINT (Ctrl+C), SIGTERM (kill) |
功能作用详解
1. case 语句详解
case "$变量" in模式1)命令块1 ;;模式2)命令块2 ;;*)默认命令块 ;;
esac
-
模式类型:
模式 示例 匹配场景 固定字符串 "start"
精确匹配字符串 通配符 "*.log"
匹配.log结尾 字符组 [Yy]
匹配Y或y 或连接 `“stop” “halt”` -
生产应用:
# 服务状态管理 case "$status" inrunning) echo "服务运行中" ;;exited) echo "服务已停止" ;;*) echo "未知状态" ;; esac
2. 函数高级技巧
# 带参数的函数
calc() {local result=$(( $1 $2 $3 )) # local声明局部变量echo $result
}# 调用
sum=$(calc 15 + 7) # 输出22
-
关键特性:
-
局部变量:
local var=value
避免污染全局命名空间 -
返回值限制:仅能返回
0-255
整数(通过echo
输出字符串结果) -
函数库重用:
source /lib/common_functions.sh # 加载函数库
-
3. 中断控制场景
命令 | 作用范围 | 功能描述 | 典型应用 | 注意事项 |
---|---|---|---|---|
break | 循环体内 | 终止当前循环 | 满足条件提前退出 | 支持break N 跳出多层 |
continue | 循环体内 | 跳过本次迭代 | 过滤特定元素 | 避免死循环 |
exit N | 脚本任意位置 | 终止脚本执行 | 返回状态码 | 0 成功, 非0 失败 |
return N | 函数内部 | 函数返回值 | 传递执行状态 | 仅限函数内使用 |
trap | 脚本全局 | 信号捕获处理 | 资源清理 | 支持多个信号 |
- 常用信号列表:
信号 | 值 | 触发方式 | 默认行为 | 捕获场景 |
---|---|---|---|---|
SIGINT | 2 | Ctrl+C | 终止进程 | 优雅关闭应用 |
SIGTERM | 15 | kill 命令 | 终止进程 | 容器停止信号 |
SIGHUP | 1 | 终端断开 | 终止进程 | 配置重载 |
SIGUSR1 | 10 | 用户自定义 | 终止进程 | 日志轮转 |
SIGUSR2 | 12 | 用户自定义 | 终止进程 | 热更新 |
SIGPIPE | 13 | 管道破裂 | 终止进程 | 管道错误处理 |
4. 生产级脚本模板
#!/bin/bash
set -euo pipefail # 严格模式# 清理函数
cleanup() {rm -rf "$TMP_DIR"echo "清理完成"
}# 注册信号捕获
trap cleanup EXIT SIGINT SIGTERM# 创建临时目录
TMP_DIR=$(mktemp -d)
echo "临时目录: $TMP_DIR"# 主逻辑函数
main() {case "$1" indeploy)echo "部署模式" ;;test)echo "测试模式" ;;*)echo "无效模式" ;;esac
}# 执行入口
main "$@"
综合案例:菜单交互系统
#!/bin/bash
# 显示菜单
show_menu() {echo "1. 系统信息"echo "2. 磁盘使用"echo "3. 退出"
}# 处理选择
handle_choice() {case $1 in1)echo "主机名: $(hostname)"echo "内核: $(uname -r)" ;;2)df -h / ;;3)echo "再见!"exit 0 ;;*)echo "无效选择" ;;esac
}# 主循环
while true; doshow_menuread -p "请选择: " choicehandle_choice "$choice"
done