目录
- 一、shell函数
- 1、shell函数的定义
- 二、函数传参
- 三、阶乘
- 四、函数实验题目
一、shell函数
使用函数可以避免代码重复
使用函数可以将大的工程分割为若干小的功能模块,代码的可读性更强
1、shell函数的定义
函数返回值:
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值使用原则:
1、在函数内用return退出函数开返回函数的值,在函数外用echo $?获取返回值,注,返回值的范用只能在0~255,超过部分需除以256取余
【1】
function 函数名 { #定义一个函数
命令序列
}
function db1 {
read -p "请输入一个整数: " value
return $[ $value * 2 ] #执行体内的函数
}
db1
echo $?
2、在函数内用echo输出值,在函数体外可用 变量=$(函数名) 获取函数的返回值
【2】
函数名() {
命令序列
}
db1 () {
read -p "请输入一个整数: " value
echo $[ $value * 2 ]
}
result=`db1`
echo $result
二、函数传参
使用函数来实现加法计算
#!/bin/bash
#定义参数
sum1() {
#函数体内部的$1 $2 代表的是调用函数时,函数后面跟的位置参数
sum=$[$1 + $2]
echo $sum
}
#调用函数
read -p "请输入第一个参数: " first
read -p "请输入第二个参数: " second
#函数体外的$1 $2 代表的是执行脚本时,脚本后面跟的位置参数
sum1 $first $second
#$first表示代表的第一个位置参数 $1
#$second表示代表的第二个位置参数 $2
使用函数来显示参数
#!/bin/bash
#定义函数
sum2() {
#函数体内部的$1 $2 代表的是调用函数时,函数后面跟的位置参数
sum=$[$1 - $2]
echo $sum
echo "在函数体内部的\$#代表调用函数时,函数后面跟的参数个数,当前函数后面有$#个参数"
echo "在函数体内部的 \$@代表调用函数时,函数后面跟的所有参数,当前函数后面的参数有: $@"
echo "在函数体内部,\$0代表$0"
}
echo "在函数体外时,\$#代表脚本后面跟的参数个数,当前脚本后面有$#个参数"
echo "在函数体外时,\$@代表脚本后面跟的所有参数,当前脚本后面参数有: $@"
echo "在函数体外. \$0代表$0"
#调用函数
#函数体外的$1 $2 代表的是执行脚本时,脚本后面跟的位置参数
sum2 $2 $1
使用函数来查看执行的顺序
脚本中的变量默认全局有效(即函数体内外都有效)
#!/bin/bash
myfun() {
echo $name
name=lisi
echo $name
}
#####main######
name=zhangsan
myfun
echo $name
在函数体内执行 local 变量 ,可将变量限定在函数体内部使用
#!/bin/bash
myfun() {
echo $name #先输出name的值
local name=lisi #加上一个local把函数体内的值限制在函数体内使用,不会显示在函数体内(局部变量)
echo $name
}
#函数值在没有调用前是不会执行的
#####main######
name=zhangsan #全局有效的变量
myfun #调用myfun这个函数
echo $name #看里面是不是全局变量,如果是局部变量,就输出体外的变量值
将全局变量删掉后,可以发现写入的只有局部变量的值,其他的值都为空
#!/bin/bash
myfun() {
echo $name
local name=lisi #使用local时只能在函数体内使用
echo $name
}
#####main######
myfun
echo $name
三、阶乘
使用函数来实现递归阶乘
#!/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"
使用函数递归来查看目录下的文件,并且有层级关系
#!/bin/bash
#使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录则输出目录名且输出此目录下的所有目录和文件名
listf () {
for f in $(ls $1) #$1是/var/log/下的子目录
do
if [ -d "$1/$f" ] #用if语句来判断是否为目录
then
echo "$2目录$f"
listf "$1/$f" " $2"
#使用空格来缩进,查到到所有目录,直到文件才执行else命令
else
echo "$2文件$f"
fi
done
}
listf "/var/log" " " #使用空格键来分割目录和文件,变的更加清晰可见
四、函数实验题目
1、通过脚本输出环境变量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目录
#遍历PATH变量的目录,并用函数递归查询
for path in $folder #使用for循环来遍历查找的目录
do
echo $path
listf "$path" " " #加上空格更加清晰看出不可执行权限的文件
done
2、将一个点分十进制格式的IP地址转换成点分二进制格式
#比如 255.255.255.255 --> 11111111.11111111.11111111.11111111
#!/bin/bash
#将一个点分十进制格式的IP地址转换成点分二进制格式
#比如 255.255.255.255 --> 11111111.11111111.11111111.11111111
#定义一个用于十进制转换为二进制的函数
switch_bin() {
NUM=$1
for i in {1..8}
do
SUM=$[NUM % 2]$SUM #取余数,结果拼接到a前,完成余数倒排
let NUM/=2 #将num除二,进入下一个循环
done
echo $SUM
}
#定义一个用于分割IP的函数
SPT() {
IP=$1
for i in {1..4}
do
num=${IP%%.*}
IP=${IP#*.}
BIN=$(switch_bin num)
echo -n $BIN.
done
}
#####main#####
read -p "请输入一个合法IP:" INIP
res=$(SPT $INIP) #使用SPT函数,下面的函数可以调用上面的函数
echo ${res%.*}
3、创建一个函数库,可以方便的使用函数脚本
jiafa() {
echo $[$1 + $2]
}
jianfa() {
echo $[$1 -$2]
}
chengfa() {
echo $[$1 * $2]
}
chufa() {
if [ $2 -eq 0 ];then
echo "除数不可为0"
else
echo $[$1 / $2]
fi
}
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
}
4、使用函数库来实现加减乘除
#!/bin/bash
#加载函数库文件到当前脚本的shell
. /root/ky111/funcs
value1=10
value2=5
res1=$(jiafa $value1 $value2)
res2=$(jianfa $value1 $value2)
res3=$(chengfa $value1 $value2)
res4=$(chufa $value1 $value2)
res5=$(fact $value1 $value2)
echo "加法的结果为$res1"
echo "减法的结果为$res2"
echo "乘法的结果为$res3"
echo "除法的结果为$res4"
echo "阶乘的结果为$res5"