文章目录
- shell函数
- shell函数的作用
- 函数返回值
- 函数传参
- 函数变量作用范围
- 递归
- 阶乘
- 使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录则输出目录名且输出此目录下的所有目录和文件名
- 通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
- 将IP地址转换成二进制
- 函数库
shell函数
shell函数的作用
- 使用函数可以避免代码重复
- 使用函数可以将大的工程分割为若干个小的功能模块,代码的可读性更强
shell函数两种定义方法
- 方法一
function 函数名 { ##函数名的唯一限制是不要与系统变量冲突
命令
}
- 方法二
函数名() {
命令
}
函数返回值
两种获取函数返回值的方法:
- 方法一:return
- return表示退出函数并返回一个退出值,脚本中可以用 $? 变量显示该值
- 使用原则:
- 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
- 退出状态码必须是0~255,超出时值将为除以256取余
- 方法二:在函数中使用echo
- 在函数中不使用return,在函数外获取函数的执行结果,用一个变量获取这个值,最后获取变量的值
##定义函数
function test1 { ##函数名的唯一限制是不要与系统变量冲突
read -p "输入一个数:" a
return $[$a * 2] ##返回值为 0-255 之间 超过部分 /256取余数
}
##### main #####
test1 ##调用函数
echo $?
db1 () {
read -p "请输入一个数:" a
echo $a
}
##### main #####
result=`db1` ##或 $(函数名) result=$(db1)
echo $result
函数传参
sum1(){
sum=$[$1+$2] ##这个是调用函数时的位置参数
echo $sum
}
read -p "第一个数" a
read -p "第二个数" b
sum1 $a $b
##在调用函数时,后面加上位置参数
sum1(){
sum=$[$1-$2] ##调用函数时的位置参数
echo $sum
echo "在函数内,\$#表示函数后面有$#个参数"
echo "在函数内,\$@表示函数后面全部参数为 $@"
echo "在函数内,\$0表示$0"
}
sum1 $2 $1 ##调用脚本时的位置参数
echo "在函数外,\$#表示脚本后面有$#个参数"
echo "在函数外,\$@表示脚本后面全部参数为 $@"
echo "在函数外,\$0表示$0"
函数变量作用范围
- 函数只能在shell脚本中仅在当前shell环境有效,使用source执行脚本,也会影响系统当前shell环境
- Shell脚本中变量默认全局有效
- 将变量限定在函数内部使用local命令
test(){
echo $name
name=1
echo $name
}
name=2
test
echo $name
test(){
echo $name
local name=1 ##local 使参数只在函数内有效
echo $name
}
name=2
test
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"
使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录则输出目录名且输出此目录下的所有目录和文件名
#!/bin/bash
list() {
for f in $(ls $1)
do
if [ -d "$1/$f" ];then
echo "$2目录$f"
list "$1/$f" " $2"
else
echo "$2文件$f"
fi
done
}
list "/var/log" ""
通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
#!/bin/bash
##定义一个遍历PATH环境变量的函数
list() {
IFSB=$IFS
IFS=$IFS':'
for i in $PATH
do
echo $i
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#####
folder=$(list)
for path in $folder
do
echo $path
listf "$path" " "
done
将IP地址转换成二进制
#!/bin/bash
##定义一个将十进制转换成二进制的函数
switch_bin() {
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=$(switch_bin num)
echo -n $BIN.
done
}
#####mian#####
read -p "请输入一个合法的IP:" INIP
res=$(SPT $INIP)
echo ${res%.*}
函数库
随便定义一个文件,在文件中写好函数,当脚本文件需要时,只需要调用文件中的函数
###函数库文件
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
}
随便写一个脚本文件,调用函数库文档
##脚本文件调用函数库
#!/bin/bsah
##加载函数库文档到当前脚本的shell
. /opt/jisuan
value1=10
value2=5
res1=$(jiafa $value1 $value2)
res2=$(jianfa $value1 $value2)
res3=$(chengfa $value1 $value2)
res4=$(fact $value1 $value2)
echo "加法和为:" $res1
echo "减法为:" $res2
echo "乘法为:" $res3
echo "阶乘为:" $res4