一、shell函数
1、创建函数
格式1
function 函数名 {
命令序列
}
格式2
函数名() {
命令序列
}
2、shell函数的基本操作
# 查看当前已定义的函数名
declare -F
# 查看当前已定义的函数定义
declare -f
# 查看指定当前已定义的函数名
declare -f func_name
# 查看当前已定义的函数名定义
declare -F func_name
二、函数返回值
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
使用原则:
1、函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
2、退出状态码必须是0~255,超出时值将为除以256取余
示例:
#!/bin/bash
function db {
read -p "输入一个值:" num
echo $[$num * 2]
}
a=$(db)
echo $a
三、函数传参
例
sum1() {
sum=$[$1 + $2]
echo $sum
}
read -p "输入第一个参数:" first
read -p "输入第二个参数:" second
sum1 $first $second
sum2() {
sum=$[$1 + $2]
echo $sum
}
sum2 $1 $2
四、函数变量的作用范围
函数在Shell脚本中仅在当前Shell环境中有效
Shell脚本中变量默认全局有效
将变量限定在函数内部使用local命令
例
#!/bin/bash
db() {
echo $a
local a=10 #在函数体内执执行local 变量,可将变量限定在函数体内部使
#用,即local定义的变量值只能在函数体内部使用,出了函数体将无法使用
echo $a
}
#####main######
a=100
db
echo $a
五、函数的调用
调用方式
可在交互式环境下定义函数
可将函数放在脚本文件中作为它的一部分
可放在只包含函数的单独文件中
例1
使用函数的方式,将标准输入获得十进制IP地址转化为二进制的IP地址
#!/bin/bash
#定义一个用于十进制转化成二进制的函数
function bin {
SUM=''
NUM=$1
for i in {1..8}
do
SUM=$[NUM%2]$SUM
let NUM/=2
done
echo $SUM
}
#定义一个用分割IP的函数
SPT (){
IP=$1
for i in {1..4}
do
num=${IP%%.*}
IP=${IP#*.}
#使用bin函数进行转化
BIN=$(bin $num)
echo -n $BIN.
done
}
####################main##################
read -p "请输入一个十进制的IP地址:" SIP
RES=$(SPT $SIP)
echo "输出的二进制IP为:" ${RES%.*}
例2
使用函数的方式打印一个菱形,并且能够通过标准输入的方式来控制该菱形的大小
#!/bin/bash
#用来打印菱形上半部分的函数
shang (){
i=1
NUM=$1
while [ $i -le $NUM ]
do
a=$NUM
while [ $a -ge $i ]
do
echo -n ' '
let a--
done
b=1
while [ $b -le $i ]
do
echo -n '*'
let b++
done
c=2
while [ $c -le $i ]
do
echo -n '*'
let c++
done
echo ""
let i++
done
}
#用来打印菱形下半部分的函数
xia (){
let d=$1-1
while [ $d -ge 1 ]
do
e=$1
while [ $e -ge $d ]
do
echo -n ' '
let e--
done
f=$[(2*d)-1]
g=1
while [ $g -le $f ]
do
echo -n '*'
let g++
done
let d--
echo ""
done
}
######################main#####################
read -p "请输入一个数字来控制函数的大小(数字越大菱形越大):" num
shang $num
xia $num
六、递归调用
函数调用本身
例:使用函数实现阶乘运算
[root@clr /opt/mywork]# vim 3.sh
#!/bin/bash
#使用函数的递归实现阶乘
fact() {
if [ $1 -eq 1 ];then
echo 1
elif [ $1 -gt 1 ];then
local tmp=$[$1 - 1]
local res=$(fact $tmp) #在函数内调用函数
echo $[$1 * res]
else
echo "输入的值无效。请输入大于等于1的整数!"
fi
}
#####main#####
read -p "请输入一个大于等于1的整数:" num
res=$(fact $num)
echo "$num的阶乘值为$res"
例:
通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
#!/bin/bash
#通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
#定义一个遍历PATH环境变量的函数
list_path() {
IFSB=$IFS
IFS=$IFS':'
for F in $PATH
do
echo "$F"
done
IFS=$IFSB
}
#定义一个递归函数
listf() {
for F in $(ls $1)
do
if [ -d "$1/$F" ];then
echo "$2$F"
listf "$1/$F" " $2"
else
if [ ! -x "$1/$F" ];then
echo "$2$F"
fi
fi
done
}
######main######
#获取PATH变量的所有目录列表
folder=$(list_path)
#遍历PATH变量的目录,并用函数递归查询
for path in $folder
do
echo $path
listf "$path" " "
done
七、函数库文件的使用
将常用的函数存入一个单独的函数文件,然后将函数文件载入shell,再进行调用函数.
第一步:搭建函数库
jia(){
echo $[$1+$2]
}
jian(){
echo $[$1-$2]
}
cheng(){
echo $[$1*$2]
}
chu(){
if [ $2 -ne 0 ];then
echo $[$1/$2]
else
echo "除数不能为0"
fi
}
jiecheng(){
if [ $1 -eq 1 ];then
echo 1
else
local temp=$[$1 -1]
local result=$(fact $temp)
echo $[$1 * $result]
fi
}
第二步:调用函数库
#!/bin/bash
#调用函数库
source /xunhuan6/myfunction
#获取输入的两个变量
read -p "请输入第一个正整数:" a
read -p "请输入第二个正整数:" b
#调用函数库中的方法,将值赋予变量
r1=$(jiafa $a $b)
r2=$(jianfa $a $b)
r3=$(chengfa $a $b)
r4=$(chufa $a $b)
r5=$(jiecheng $a)
#输出变量
echo "加法的运算结果为:" $r1
echo "减法的运算结果为:" $r2
echo "乘法的运算结果为:" $r3
echo "除法的运算结果为:" $r4
echo "阶乘的运算结果为:" $r5