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

【网络运维】Shell脚本编程:函数

Shell脚本编程:函数

Shell 函数介绍

在 Shell 编程中,函数是一种非常重要的代码组织和复用机制。我们可以将函数理解为一种“高级别名”,它不仅能够简化代码,还能提高程序的可读性和可维护性。

alias 类似,函数可以封装常用操作:

# 使用 alias 简化命令
alias ll='ls -l --color=auto'
ll /home/

但函数比 alias 更强大,它能够:

  • 减少代码重复,提升开发效率
  • 增强程序可读性和可管理性
  • 实现程序功能模块化,提高可移植性

Shell 函数的语法

Shell 函数有三种常见的定义方式:

标准写法

function 函数名 () {指令...return n
}

简化写法1:省略小括号

function 函数名 {指令...return n
}

简化写法2:省略 function 关键字

函数名 () {指令...return n
}

Shell 函数的执行

1. 执行不带参数的函数

直接输入函数名即可(不需要小括号):

函数名

重要说明:

  • 函数定义必须在调用之前
  • Shell 执行优先级:系统别名 → 函数 → 系统命令 → 可执行文件
  • 函数内使用 return 退出函数,exit 退出整个脚本
  • 使用 local 定义局部变量,这些变量在函数外不可见
  • 独立函数文件需要使用 source. 加载

2. 执行带参数的函数

函数名 参数1 参数2

参数说明:

  • 使用 $1, $2$n 获取参数
  • $# 表示参数个数,$*$@ 表示所有参数
  • $0 仍然是父脚本的名称
  • 函数参数会临时覆盖父脚本的参数

Shell 函数实践示例

示例1:基础 hello 函数

#!/bin/bash
# 定义函数
function hello () {echo "Hello World !"
}
# 调用函数
hello

执行结果:

Hello World !

错误示例:先调用后定义

#!/bin/bash
hello  # 此时函数还未定义,会报错
function hello () {echo "Hello World !"
}

执行结果:

fun2.sh: line 2: hello: command not found

关键点:函数必须先定义后调用

示例2:调用外部函数文件

创建函数库文件:

# 创建名为 mylib 的函数库
cat >> mylib << 'EOF'
function hello () {echo "Hello World !"
}
EOF

在主脚本中调用:

#!/bin/bash
# 检查函数库是否存在并可读
if [ -r mylib ]; thensource mylib  # 加载函数库
elseecho "mylib does not exist or is not readable"exit 1
fihello  # 调用函数

执行结果:

Hello World !

关键点:使用 source. 命令加载外部函数定义

示例3:带参数的函数

#!/bin/bash
function print () {# 根据参数值输出不同颜色的文本if [ "$1" == "PASS" ]; thenecho -e '\033[1;32mPASS\033[0;39m'  # 绿色elif [ "$1" == "FAIL" ]; thenecho -e '\033[1;31mFAIL\033[0;39m'  # 红色elif [ "$1" == "DONE" ]; thenecho -e '\033[1;35mDONE\033[0;39m'  # 紫色elseecho "Usage: print PASS|FAIL|DONE"fi
}# 获取用户输入
read -p "请输入你想要打印的内容:" str
print $str  # 调用函数并传递参数

测试结果:

# 运行脚本
请输入你想要打印的内容:PASS
PASS(绿色显示)请输入你想要打印的内容:hello
Usage: print PASS|FAIL|DONE

关键点:函数内部通过 $1 获取第一个参数

示例4:函数参数与脚本参数

#!/bin/bash
function print () {if [ "$1" == "PASS" ]; thenecho -e '\033[1;32mPASS\033[0;39m'elif [ "$1" == "FAIL" ]; thenecho -e '\033[1;31mFAIL\033[0;39m'elif [ "$1" == "DONE" ]; thenecho -e '\033[1;35mDONE\033[0;39m'else# 注意:这里的 $0 仍然是脚本名,不是函数名echo "Usage: $0 PASS|FAIL|DONE"fi
}str=$2  # 获取脚本的第二个参数
print $str  # 传递给函数

测试结果:

bash fun5.sh PASS FAIL
FAIL  # 显示的是第二个参数FAIL,而不是第一个参数PASSbash fun5.sh
Usage: fun5.sh PASS|FAIL|DONE  # $0 显示脚本名

关键点:函数参数会覆盖脚本参数,但 $0 始终指向脚本名称

函数实战:URL检测脚本

#!/bin/bash
# 使用方法提示函数
function usage () {echo "usage: $0 url"exit 1
}# URL检测函数
function check_url () {# 使用wget检测URL可访问性wget --spider -q -o /dev/null --tries=1 -T 5 $1# 根据返回状态码判断结果[ $? -eq 0 ] && echo "$1 is accessible" || echo "$1 is not accessible"
}# 主函数
function main () {# 检查参数个数是否正确[ $# -ne 1 ] && usagecheck_url $1
}# 执行主函数,传递所有参数
main $*

测试结果:

bash check_url.sh www.baidu.com
www.baidu.com is accessiblebash check_url.sh www.nonexistent.com
www.nonexistent.com is not accessible

关键点:模块化设计,分离功能逻辑,提高代码可维护性

函数的递归调用

示例1:计算1到n的累加和

#!/bin/bash
function sum_out() {if [ $1 -eq 1 ]; thensum=1  # 递归基线条件else# 递归调用:n + (n-1)的和sum=$[ $1 + $(sum_out $[ $1 - 1 ]) ]fiecho $sum
}read -p "输入一个你想计算和的整数:" num
sum_out $num

示例2:计算n的阶乘

#!/bin/bash
function fact_out() {if [ $1 -eq 1 ]; thensum=1  # 递归基线条件else# 递归调用:n * (n-1)的阶乘sum=$[ $1 * $(fact_out $[ $1 - 1 ]) ]fiecho $sum
}read -p "输入一个你想计算阶乘的整数:" num
fact_out $num

示例3:fork炸弹(⚠️危险示例,请勿实际运行)

:(){ :|:& };:

代码解析:

  • :() - 定义函数名为冒号
  • { :|:& } - 函数体:递归调用自身两次,并通过管道并行执行
  • ; - 命令分隔符
  • : - 调用函数,启动炸弹

原理:无限递归创建进程,耗尽系统资源

防范措施:限制用户进程数

ulimit -u 100  # 限制用户最多100个进程
http://www.dtcms.com/a/349248.html

相关文章:

  • 大件垃圾识别精准度↑90%!陌讯多尺度融合模型在智慧环卫的落地实践
  • 鸿蒙ArkTS 基础篇-03-对象
  • 【黑色星期五输出当年有几个】2022-10-23
  • 单词搜索+回溯法
  • Windows客户端部署和管理
  • Week 13: 深度学习补遗:RNN的训练
  • 青少年软件编程(python五级)等级考试试卷-客观题(2023年12月)
  • 2024年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 使用 LangGraph + Zep 打造一款有记忆的心理健康关怀机器人
  • 【LLIE专题】一种用于低光图像增强的空间自适应光照引导 Transformer(SAIGFormer)框架
  • 超级助理:百度智能云发布的AI助理应用
  • JUC之并发容器
  • 2025最新酷狗kgm格式转mp3,kgma格式转mp3,kgg格式转mp3
  • 《程序员修炼之道》第五六章读书笔记
  • 【云馨AI-大模型】AI热潮持续升温:2025年8月第三周全球动态
  • 复杂场景横幅识别准确率↑91%!陌讯多模态融合算法在智慧园区的实战解析
  • 删掉一个元素以后全为1的最长子数组-滑动窗口
  • 【Luogu】P4317 花神的数论题 (数位DP)
  • 深度学习周报(8.18~8.24)
  • ASCII码值,可打印的字符有
  • 文档目录索引
  • 详解无监督学习的核心原理
  • 基于实例教学的软件工程专业教学系统
  • Livedata:感知生命周期变化,如何更新数据?避免内存泄漏,黏性事件
  • TCP--执行Linux命令(虚拟xshell)
  • 苍穹外卖项目实战(日记十)-记录实战教程及问题的解决方法-(day3-2)新增菜品功能完整版
  • 不再让Windows更新!Edge游戏助手卸载及关闭自动更新
  • Leetcode 3661. Maximum Walls Destroyed by Robots
  • 阿里AI模型获FDA突破性医疗器械认定,AI医疗走向国际舞台,来近屿智能系统学习AIGC大模型技术
  • 芋道前端项目部署后刷新 404 的解决办法(Nginx 配置教程)