使用函数可以避免代码重复,当我们需要写大工程代码时,可以通过函数将代码分成各个小模块,既能使代码看起来更简洁,增强可读性,又能很方便的调用。
1.函数的格式
格式一
faunction 函数名 {
命令序列
}
格式二
函数名() {
命令序列
}
2.调用函数
直接使用函数名即可调用函数脚本中
3.函数变量的作用范围
脚本中定义的函数只能在Shell脚本的当前环境中有效,出了脚本就无效;
function() {
local i
i=8
echo $i
}
i=9
myfun
echo $i
Shell脚本中定义的变量不论定义在函数里还是函数外都是全局有效的。注意:如果变量定义在函数里,那么必须要先执行函数该函数才会有效;
在函数内使用 local 变量,相当于重新定义了一个同名变量,该变量只能在函数内有效,与函数外同名的全局变量没有关系。
4.获取函数的返回值
① return获取函数的返回值。return表示退出函数时返回一个指定的值。在函数里使用return返回一个值,在脚本中(函数外)紧接着使用 $? 变量显示该值,只能返回0-255的值,超出时值将处于256取余数。(使用return返回值有局限性,不方便其他操作,且必须在函数执行完紧接着用$?获取)
#!/bin/bash
hanshu() {
read -p "请输入一个整数:" num
sum=$[$num * 2]
return $sum #值的范围在0-255之间,超出则除以256取余数
}
######### main #########
hanshu
echo $? #用来获取函数中return返回的值,前面不能有别的命令,有则$?返回的值就不是return指定的值
② 在函数里使用echo返回值,在函数外定义一个变量来获取函数的返回值(变量名=$(函数名)。此方法还可以进一步对函数返回的值添加别的操作,更加灵活
#!/bin/bash
hanshu() {
read -p "请输入一个整数:" num
sum=$[$num * 2]
echo $sum
}
######### main #########
result=$(hanshu)
echo "函数返回值double后为$[result * 2]"
5.函数的传参
demo1
demo2
demo3
#!/bin/bash
hs() {
#函数体内的$1引用的是下面执行函数后面跟的第一个位置的参数,$2引用的是第二个位置的参数
sum=$[$1 + $2]
echo $sum
}
####### main ######以下为主代码区
#函数体外的$1和$2跟的是执行脚本后面跟的第一个位置的参数和第二个位置的参数
SUM=$(hs $1 $2)
echo "$ + $2 为$SUM"
#!/bin/bash
#定义三个函数servicectl_usage、chk_centos_ver和servicectl
#第一个是关于脚本的使用方法的函数
servicectl_usage() {
echo "Usage:servicectl <service-name> <start|stop|restart|reload|status>"
return 1
}
#第二个是输出系统版本的函数
chk_centos_ver() {
grep "CentOS.*release 7." /etc/centos-release &> /dev/null && echo "7"
grep "CentOS.*release 6." /etc/centos-release &> /dev/null && echo "6"
grep "CentOS.*release 5." /etc/centos-release &> /dev/null && echo "5"
}
#第三个函数调用到前2个函数,当缺少参数时告知脚本使用方法,不缺少时判断版本是不是为7,为7执行systemctl的命令,不为7则执行service的命令
servicectl() {
[[ -z $1 || -z $2 ]] && servicectl_usage
[ $(chk_centos_ver) == "7" ] && systemctl $2 ${1}.service || service $1 $2
}
#这里的$1为执行脚本后跟的第一个参数(服务名),$2为执行脚本后面跟的第二个参数(要执行的操作)。第三个函数中的$1与$2位置与这里的位置是一致的,没有歧义。
servicectl $1 $2
注意:
①函数外的$1 $2表示的是执行脚本时脚本后面跟的第一个第二个位置的参数
②函数体里面的$1 $2表示的是调用函数时,函数名后面跟的第一个 第二个位置的参数
6.函数递归(在函数体里调用函数本身)
1)实现阶乘
#!/bin/bash
fact() {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[$1 - 1]
local result=$(fact $temp)
echo $[$1 * $result]
fi
}
read -p "请输入:" n
result=$(fact $n)
echo "$n 的阶乘为$result"
2)实现递归目录
demo:递归PATH环境变量中所有目录,输出所有不可执行的文件
6.函数库
先将一些常用的函数事先保存在一个特定的函数库文件中,需要使用时可直接在shell脚本文件开头位置用 source 函数库文件(绝对路径) 加载函数即可直接使用。
vim function.sh #函数库文件中定多个函数
source function.sh #在脚本开头加载函数库文件,然后使用函数名可以直接调用函数