shell函数
什么是shell函数
- 函数其实就是一堆命令的合集,用来完成特定功能的代码块
为何需要函数
- 比如:我们经常需要使用判断功能,完全可以将其封装为一个函数,这样在写程序过程中可以在任何地方调用该函数,不必重复编写
- 函数能减少代码冗余,增加代码的可读性
- 函数和变量类似,必须先定义才可以调用,如果定义不调用则不会被执行
函数基础语法
- 定义
shell
函数,可以通过如下两种方式进行定义
# 方式一
name()
{
command1
command2
...
commandn
}
# 方式二
function name
{
command1
command2
...
commandn
}
- 调用函数,直接使用函数名调用。(可以理解为
shell
的一条命令)
fun() { echo "hello world"; }
# 调用函数
fun
hello world
函数参数传递
在函数内部可以使用参数$1、$2...
,调用函数function_name $1 $2 ...
- 函数中传递单个参数示例
fun() { echo "hello,$1"; }
# 调用
fun monday
hello,monday
- 函数中传递多个参数示例
fun() { echo "hello,$1 $2 $3"; }
fun linux shell python
hello,linux shell python
- 函数中传递多个参数,
$*
接收所有的参数传递
fun() { echo "hello,$*"; }
fun monday tuesday wednesday thursday friday saturday sunday
hello,monday tuesday wednesday thursday friday saturday sunday
函数实现计算器功能脚本
- 需求:写一个脚本,该脚本可以实现计算器的功能,可以进行
+-*/
四周计算sh cal.sh 40 + 30
sh cal.sh 40 - 30
sh cal.sh 40 * 30
sh cal.sh 40 / 30
cat cal.sh
#!/usr/bin/bash
calsum() {
case $2 in
+)
echo "$[ $1 + $3 ]"
;;
-)
echo "$[ $1 - $3 ]"
;;
x)
echo "$[ $1 * $3 ]"
;;
/)
echo "$[ $1 / $3 ]"
;;
esac
}
#调用函数并进行参数传递
calsum $1 $2 $3
函数实现nginx启停脚本
需求:写一个脚本,实现nginx
服务的启动、停止、重启
cat nginx.sh
#!/usr/bin/bash
. /etc/init.d/functions
#定义函数,函数需要传递一个参数
nginx_when() {
if [ $? -eq 0 ];then
action "nginx $1 is ok!" /bin/true
else
action "nginx $1 is error..." /bin/false
fi
}
#接收脚本传入的第一个位置参数,然后进行匹配
case $1 in
start)
nginx
nginx_when $1
;;
stop)
nginx -s stop
nginx_when $1
;;
reload)
nginx -s reload
nginx_when $1
;;
*)
echo "USAGE: $0 { start|stop|reload }"
esac
函数状态返回值
shell
的函数返回值,也算是退出的状态,在shell
中只有echo、return
两种方式return
返回值:只能返回1-255的整数,函数使用return
返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败。echo
返回值:使用echo
可以返回任何字符串结果,通常用于返回数据,比如一个字符串值或者列表值
echo数据返回示例
cat echo.sh
#!/usr/bin/bash
get_users() {
users=$(cat /etc/passwd | awk -F ':' '{print $1}')
echo $users
}
#get_users
#可以对拿到的函数结果进行遍历
index=1
for u in $(get_users)
do
echo "the $index user is :$u"
let index++
done
shell数组
什么是数组
- 数组其实也是变量,传统的变量只能存储一个值,但数组可以存储多个值
数组的分类
shell
数组分为普通数组和关联数组- 普通数组:只能使用整数作为数组索引
- 关联数组:可以使用字符串作为数组索引
普通数组:books=(linux nginx shell)
linux | nginx | shell |
---|---|---|
0 | 1 | 2 |
普通数组下标只能是整数
关联数组:info=([name]=xiaoming [age]=18 [skill]=linux)
xiaoming | age | linux |
---|---|---|
name | age | skill |
关联数组的下标可以是字符串
数组基本使用
普通数组赋值
-
普通数组的赋值(注意:普通数组仅能使用整数来作为索引)
方式一:针对每个索引进行赋值(数组名[索引]=变量值)array[0]=pear array[1]=apple array[2]=orange
方式二:一次赋多个值(数组名=(多个变量值))
array3=(tom jack alice [20]=docker) echo ${array3[@]} tom jack alice docker echo ${!array3[@]} 0 1 2 20
普通数组元素访问
-
数组名加索引即可访问数组中的元素
echo ${array[0]} pear
-
访问数组中所有的数据
echo ${array[@]} pear apple orange
-
获取数组中的索引,在数据遍历的时候有用
echo ${!array[@]} 0 1 2
-
统计数组元素的个数
echo ${#array[@]} 3
关联数组赋值
- 关联数组的赋值(注意:关联数组能使用字符串的方式作为索引)
-
必须先申明这是一个关联数组
declare -A info
-
方式一:关联数组的赋值,数组名[索引]=变量值
info[index1]=pear info[index2]=apple info[index3]=orange
-
方式二:关联数组的赋值,数组名([索引1]=变量值1 [索引2]=变量值2)
info2=([index1]=linux [index2]=nginx [index3]=docker [index4]='bash shell')
-
查看关联数组
declare -A declare -A info='([index1]="pear" [index2]="apple" [index3]="orange" )' declare -A info2='([index4]="bash shell" [index1]="linux" [index2]="nginx" [index3]="docker" )'
关联数组访问
-
访问数组中的第二个元素
echo ${info2[index2]} nginx
-
访问数组中所有数据
echo ${info2[@]} bash shell linux nginx docker
-
访问数组中所有元素的索引
echo ${!info2[@]} index4 index1 index2 index3
普通数组场景
普通数组示例脚本
cat array01.sh
#!/usr/bin/bash
i=0
while read line
do
hosts[i++]=${line}
done < /etc/hosts
for i in ${!hosts[@]}
do
echo 索引:$i 索引对应的内容:"${hosts[$i]}"
done
# 执行结果如下
sh array01.sh
索引:0 索引对应的内容:127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
索引:1 索引对应的内容:::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
实现货币兑换系统脚本
-
根据业务需求,现要求开发一个货币兑换的服务系统,具体要求如下
- 1.实现人民币兑换美元的功能
- 2.实现美元兑换人民币的功能
- 3.实现人民币兑换欧元的功能
-
货币兑换利率:1美元=7.14人民币、1元=0.12欧元
sh exchange.sh
******欢迎使用货币转换服务系统******
====================================
1.欢迎使用 人民币转换美元 服务
您需要转换的人民币为:100 元
兑换成美元为:14.01$
====================================
2.欢迎使用 美元转换人民币 服务
您需要转换的美元为:100 $
兑换成人民币为:714RMB
====================================
3.欢迎使用 人民币转换欧元 服务
您需要转换的人民币为:100 元
兑换成欧元为:12.00欧
cat exchange.sh
#!/usr/bin/bash
your_money=100
service_menu=(人民币转换美元 美元转换人民币 人民币转换欧元)
echo "******欢迎使用货币转换服务系统******"
for service in ${!service_menu[@]}
do
if [ $service -eq 0 ];then
echo "===================================="
echo "1.欢迎使用 ${service_menu[service]} 服务"
echo "您需要转换的人民币为:$your_money 元"
new_money=$(awk -v your_money=$your_money 'BEGIN {printf "%.2f",your_money/7.14}')
echo "兑换成美元为:${new_money}$"
fi
if [ $service -eq 1 ];then
echo "===================================="
echo "2.欢迎使用 ${service_menu[service]} 服务"
echo "您需要转换的美元为:$your_money $"
new_money=$(awk -v your_money=$your_money 'BEGIN {print your_money*7.14}')
echo "兑换成人民币为:${new_money}RMB"
fi
if [ $service -eq 2 ];then
echo "===================================="
echo "3.欢迎使用 ${service_menu[service]} 服务"
echo "您需要转换的人民币为:$your_money 元"
new_money=$(awk -v your_money=$your_money 'BEGIN {printf "%.2f",your_money*0.12}')
echo "兑换成欧元为:${new_money}欧"
fi
done
获取系统所有端口的脚本
- 需求:使用
shell
数组编写脚本,用来获取主机的所有端口,效果如下:
sh discovery_port.sh
{
"data":[
{"{#TCP_PORT}":"10050"},
{"{#TCP_PORT}":"111"},
{"{#TCP_PORT}":"22"},
{"{#TCP_PORT}":"3306"},
{"{#TCP_PORT}":"80"},
{"{#TCP_PORT}":"9000"}
]
}
cat discovery_port.sh
#!/usr/bin/bash
# 数组
array_port=($(netstat -lntp | awk '{print $4}' | awk -F : '{print $NF}' | egrep "^[0-9]+" | sort | uniq))
# 统计数组的长度
array_langth=${#array_port[@]}
# 定义一个变量
index=1
# 遍历数组,组装数据
printf "{\n"
printf "\t\"data\":[\n"
for port in ${array_port[@]}
do
if [ $index -eq $array_langth ];then
printf "\t\t{\"{#TCP_PORT}\":\"$port\"}\n"
else
printf "\t\t{\"{#TCP_PORT}\":\"$port\"},\n"
fi
index=$[ index + 1 ]
done
printf "\t]\n"
printf "}\n"
数组遍历与循环
什么是数组遍历
- 数组遍历其实就是使用对数组进行批量赋值,然后通过循环方式批量取出数组的值
数组遍历的意义
-
数组遍历的意义在于,统计某个字段出现的次数,那么遍历的方式有如下两种:
- 1.通过数组的个数进行遍历(不推荐)- 2.通过数组的索引进行遍历(推荐)
-
如果需要统计一个文件中某个字段出现的次数,怎么办?
- 要统计谁就将谁作为数组的索引,然后获取索引出现的次数
- 值得一提的是该方法仅支持关联数组
关联数组统计示例脚本
统计文件中男生、女生出现的次数
- 准备对应的文件
cat sex.txt
jack m
alice f
tom m
rose f
robin m
yj m
cindy f
# 第二列作为索引名称,然后让索引名称自增,出现一次+1
# 遍历这个索引,取出对应的值,次数
- 编写遍历脚本
cat count_sex.sh
#!/usr/bin/bash
declare -A sex
# 对数组进行赋值
while read line
do
# 取出第二列的内容
type=$(echo $line | awk '{print $2}')
# 定义一个关联数组,让数组的值不断自增
let sex[$type]++
done < sex.txt
# 遍历数组
for i in ${!sex[@]}
do
echo "$i ${sex[$i]}"
done
- 步骤拆分讲解
declare -A sex
sex=([m]=1 [f]=1)
let sex[m]++
let sex[f]++
echo ${!sex[@]}
f m
echo ${sex[@]}
2 2
统计shell类型次数脚本
需求:使用shell
数组统计/etc/passwd
的不同shell
类型的数量
cat shell_count.sh
#!/usr/bin/bash
declare -A shell
# 对数组进行赋值
while read line
do
type=$(echo $line | awk -F : '{print $NF}')
let shell[$type]++
done < /etc/passwd
# 对数组进行遍历
for i in ${!shell[@]}
do
echo 索引是$i,索引的值是:${shell[$i]}
done
统计nginx ip次数脚本
需求:使用shell
数组统计/var/log/nginx/access.log
文件,相同ip
访问的次数
cat array_nginx_count.sh
#!/usr/bin/bash
declare -A nginx
# 给关联数组的索引进行赋值
while read line
do
type=$(echo $line | awk '{print $1}')
let nginx[$type]++
done < /var/log/nginx/access.log
# 遍历数组
for i in ${!nginx[@]}
do
echo "IP是:$i 出现的次数是 ${nginx[$i]}"
done
留言