Shell 编程(二):Shell 函数的高级用法
2023-03-07 09:45:10 时间
函数定义和使用
- Linux Shell 中的函数和大多数编程语言中的函数一样
- 将相似的任务或代码封装到函数中,供其他地方调用
语法格式
方法 | 格式内容 |
---|---|
方法一 | name() { command1 command2 … conmandn } |
方法二 | function name{ command1 command2 … commandn} |
#!/bin/bash
# 方法一
test()
{
echo "test function";
}
# 方法二
function greeting
{
echo "hello,Zhangsan";
}
test
greeting
输出
test function
hello,Zhangsan
例子
写一个监控nginx的脚本;如果Nginx服务宕掉,则该脚本可以检测到并将进程启动;如果正常运行,则不做任何处理。
# nginx_daemon.sh
#!/bin/bash
# 获取当前脚本运行的子id,防止 ps 命令误认
this_pid=$$
while true
do
ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null
if [ $? -eq 0 ];then
echo "Nginx is running well"
sleep 3
else
systemctl start nginx
echo "Nginx is down,Start it ..."
fi
done
# bash
> nohup sh nginx_ daemon. sh &
[1] 76378
> tail -f nohup.out
Nginx is running well
Nginx is running well
Nginx is running well
Nginx is running well
- 直接使用函数名调用,可以将其想象成 Shell 中的一条命令
- 函数内部可以直接使用参数1、2…、
函数传参
调用格式
# name 为函数
name xxx xxx
> function greeting
> {
> echo "hello,$1"
> }
> greeting chendasheng
hello chendasheng
例子
写一个脚本,该脚本可以实现计算器的功能,可以进行 +、-、*、/ 四种计算。
# example3.sh
#!/bin/bash
function calculate
{
case "$2" in
+)
echo "`expr $1 + $3`";
;;
-)
echo "`expr $1 - $3`";
;;
\*)
echo "`expr $1 \* $3`";
;;
/)
echo "`expr $1 / $3`";
;;
esac
}
calculate $1 $2 $3
# bash
> sh example3.sh 5 + 6
11
> sh example3.sh 100 / 6
16
函数返回值
方法 | 函数 |
---|---|
方法一 | return |
方法二 | echo |
使用 return 返回值
- 使用return返回值,只能返回 1-255 的整数
- 函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回 0 或 1 ; 0 表示成功, 1 表示失败
使用echo返回值
- 使用echo可以返回任何字符串结果
- 通常用于返回数据,比如一个字符串值或者列表值
例子
Nginx 函数引用返回值
#!/bin/bash
this_pid=$$
function is_nginx_running
{
ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null
if [ $? -eq 0 ];then
return
else
return 1
fi
}
is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"
局部变量和全局变量
全局变量
- 不做特殊声明, Shell中变量都是全局变量
大型脚本程序中函数中慎用全局变量
局部变量
- 定义变量时,使用local关键字
- 函数内和外若存在同名变量,则函数内部变量覆盖外部变量
例子
# example5.sh
#!/bin/bash
var1="Hello world"
function test
{
var2=87
local var3=86
echo $var3
}
echo $var1
echo $var2
echo $var3
test
echo $var1
echo $var2
echo $var3
function test1
{
echo $var2
echo $var3
}
test1
输出
> sh example5.sh
Hello world
86
Hello world
87
87
函数库
为什么要定义函数库,
- 经常使用的重复代码封装成函数文件
- 一般不直接执行,而是由其他脚本调用
例子
定义一个函数库,该函数库实现以下几个函数:
- 加法函数 add
- 减法函数 reduce
- 乘法函数 multiple
- 除法函数 divide
- 打印系统运行情况的函数sys_load,该函数可以显示内存运行情况,磁盘使用情况
# base_function.lib
function add
{
echo "`expr $1 + $2`"
}
function reduce
{
echo "`expr $1 - $2`"
}
function multiple
{
echo "`expr $1 \* $2`"
}
function divide
{
echo "`expr $1 / $2`"
}
function sys_load
{
echo "Memory Info"
echo
free -m
echo
echo "Disk Info"
echo
df -h
echo
}
# example6.sh
#!/bin/bash
. /Users/chendashengpc/code/shell/advanced-usage-of-function/base_function.lib
add 1 3
reduce 3 4
multiple 7 8
divide 9 10
sys_load
输出
4
-1
56
0
Memory Info
total used free shared buff/cache available
Mem: 7678 2371 461 84 4844 4924
Swap: 0 0 0
Disk Info
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.8G 16K 3.8G 1% /dev/shm
tmpfs 3.8G 572K 3.8G 1% /run
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
/dev/vda1 79G 19G 57G 26% /
tmpfs 768M 0 768M 0% /run/user/1001
tmpfs 768M 0 768M 0% /run/user/0
经验之谈
- 库文件名的后缀是任意的,但一般使用 .lib
- 库文件通常没有可执行选项
- 库文件无需和脚本在同级目录,只需在脚本中引用时指定
- 第一行一般使用 #!/bin/echo 输出警告信息,避免用户执行
相关文章
- 新增功能 — Amazon Genomics CLI 现已开源并全面推出
- Amazon Connect 的新功能:Voice ID、Wisdom 和出站通信
- dispose java_Java Context.dispose方法代码示例
- python httplib 模块
- 在中国区使用 Amazon IoT 和 Amazon SageMaker 进行设备实时预测性维护
- AWS Cloud Builders – 职业跨界与个人成长
- Amazon QuickSight Q – 使用自然语言的业务情报问题
- 即将推出 – AWS 新西兰区域
- AWS IQ 扩展:与英国和法国的专家和咨询公司联系
- AWS 如何支持受飓风艾达影响的非营利组织、政府和社区
- 在Amazon EKS中获取客户端真实源IP不同方式
- 新增 – 用于实时多流视频转码的 Amazon EC2 VT1 实例
- 专为构建者打造:AWS 和开放式 3D 引擎的故事 — 开发人员预览
- DeepRacer解决无法登录Console以及模型失效的方法
- 使用AWS 媒体服务构建全球直播解决方案
- 监控告警一点通:在CloudWatch上为 EC2批量添加告警
- 基于ECS Fargate构建Apache Superset
- 【Java】Java实现批量打包文件Zip下载
- 使用Amazon SageMaker部署CVAT AI自动图像标注系统
- Amazon EKS Anywhere – 现已正式发布,可在本地创建和管理 Kubernetes 集群