8.5 函数

系列 - LINUX Shell脚本
目录
本教学实验手册介绍了如何在Bash脚本中定义和使用函数,包括基本格式、函数参数的传递和使用。通过示例展示了如何避免代码重复,提高可维护性,并提供了多参数函数的练习,最后通过一个王者荣耀英雄技能模拟器的综合作业,帮助理解脚本参数和函数参数的区别与使用。
任务一:函数function
在日常编程中,我们经常需要重复使用某段代码。为了避免代码重复编写,提高代码的可维护性,Shell脚本提供了函数(function)功能。
在Bash脚本中,函数的基本格式如下:
function 函数名() {
# 函数体
}
说明
- function关键字可以省略,但建议保留以提高代码可读性
- 函数必须先定义后使用(重要)
- 函数名要符合标识符命名规范,建议使用有意义的英文名称
让我们来看一个简单的函数使用示例:
#!/bin/bash
# 脚本名:func01.sh
function print_choice() {
echo -n "你的选择是:" # -n参数不换行
}
echo "这个脚本将显示你的选择"
case $1 in
"one")
print_choice; echo $1
;;
"two")
print_choice; echo $1
;;
"three")
print_choice; echo $1
;;
*)
echo "使用方法:$0 {one|two|three}"
;;
esac
代码说明
- 定义了一个名为
print_choice
的函数,用于打印固定的提示文字 - 在
case
语句的每个分支中都调用了这个函数 - 通过这种方式,我们避免了重复编写
echo
语句 -n
参数使echo
命令输出后不换行,这样后续的内容会接在同一行
运行结果:
从上面的例子中可以看出,当一段代码会被多次使用时,将这段代码放进一个函数内是非常合适的选择。
函数参数的使用
和普通Shell脚本一样,函数也可以接收参数。在函数中使用参数的方式与脚本参数完全相同:
- $1 表示第一个参数
- $2 表示第二个参数
- 以此类推…
下面是一个使用函数参数的改进版本:
#!/bin/bash
# 脚本名:func02.sh
function print_choice() {
echo "你的选择是:$1" # -n参数不换行
}
echo "这个脚本将显示你的选择"
case $1 in
"one")
print_choice 1
;;
"two")
print_choice 2
;;
"three")
print_choice 3
;;
*)
echo "使用方法:$0 {one|two|three}"
;;
esac
改进说明
- 函数print_choice现在接收一个参数
- 在函数内通过$1访问这个参数
- 调用函数时直接在函数名后面跟上参数值
- 这样使函数更加灵活,可以显示不同的选择结果
运行结果:
注意事项
- 函数的参数与脚本的参数是独立的
- 在函数内部,$1代表传递给函数的第一个参数,而不是脚本的第一个参数
- 调用函数时参数之间用空格分隔
练习一:多参数的函数
假设我们需要管理学生的考试成绩,设计一个函数来计算每个学生的平均分并给出评级。这个练习既实用,又能很好地展示多参数函数的应用。
#!/bin/bash
# 文件名:grade_manager.sh
# 函数:计算平均分并评级
function calc_grade() {
# 接收四个参数:学生姓名、语文分数、数学分数
student_name=$1
chinese=$2
math=$3
# 计算平均分
local average=$(( ($chinese + $math) / 2 ))
# 根据平均分确定等级
if [ $average -ge 90 ]; then
level="优秀"
elif [ $average -ge 80 ]; then
level="良好"
elif [ $average -ge 70 ]; then
level="中等"
elif [ $average -ge 60 ]; then
level="及格"
else
level="不及格"
fi
# 输出结果
echo "学生:$student_name"
echo "语文:$chinese"
echo "数学:$math"
echo "平均分:$average"
echo "评级:$level"
echo "------------------------"
}
# 主程序
echo "==== 学生成绩管理系统 ===="
# 调用函数计算多个学生的成绩
calc_grade "张三" 85 92
calc_grade "李四" 76 83
calc_grade "王五" 92 95
代码说明
- 函数
calc_grade
接收4个参数:- $1:学生姓名
- $2:语文成绩
- $3:数学成绩
- $4:英语成绩
- 使用算术运算
$(( ))
计算平均分 - 使用if-elif结构判断成绩等级:
- 最后格式化输出所有信息
运行结果:
综合作业
作业目的
通过制作一个简单的技能伤害计算器,理解 Shell 脚本的基本语法和参数使用。
#!/bin/bash
# 文件名:skill_damage.sh
# 计算技能伤害的函数
# 参数:$1-技能伤害 $2-法术攻击 $3-魔抗值
function calc_damage() {
# 获取参数
skill_damage=$1 # 技能基础伤害
magic_attack=$2 # 法术攻击力
magic_defense=$3 # 魔法防御值
# 计算最终伤害
final_damage=$(( (skill_damage + magic_attack) * (1000 - magic_defense) / 1000 ))
# 返回计算结果
echo $final_damage
}
# 检查参数数量
if [ $# -ne 3 ]; then
echo "使用方法: ./skill_damage.sh 英雄名称 法术攻击 魔抗值"
echo "例如: ./skill_damage.sh 王昭君 500 200"
exit 1
fi
# 获取参数
hero=$1 # 英雄名称
magic=$2 # 法术攻击
defense=$3 # 魔抗值
echo "=== 王者荣耀伤害计算器 ==="
echo "英雄:$hero"
echo "法术攻击:$magic"
echo "敌方魔抗:$defense"
echo "======================="
# 计算并显示技能伤害
case $hero in
"王昭君")
damage=$(calc_damage 400 $magic $defense)
echo "凛冬已至:$damage"
;;
"妲己")
damage=$(calc_damage 450 $magic $defense)
echo "偶像魅力:$damage"
;;
"安琪拉")
damage=$(calc_damage 500 $magic $defense)
echo "火球术:$damage"
;;
*)
echo "暂不支持该英雄"
exit 1
;;
esac
作业要求:
- 理解并运行上述代码,体会参数的使用方法
- 完成以下任务:
# 添加一个判断是否击杀的函数
# 参数:$1-造成的伤害 $2-目标血量
function check_kill() {
# 请补充代码:
# 1. 如果伤害大于血量,显示"击杀成功!"
# 2. 否则显示"还需要xx点伤害"
}
# 在主程序调用这个函数测试
check_kill $damage 600
运行结果示例: