Linuxshell脚本之函数Function详解
Linux shell脚本之函数Function
函数详解
在过程式编程中,代码会重⽤。过程式编程⼜分为:模块化编程和结构化编程。
把代码重⽤的代码段进⾏命名,并重复调⽤,这就是函数。
函数(function):把⼀段独⽴功能的代码当作⼀个整体,并为之命名⼀个名字,成为命名的代码段,此即为函数。在使⽤函数时,需要注意以下⼏点:
1、定义函数的代码段在定义时是不会被执⾏的,在调⽤时才会被执⾏。
2、在脚本中如果想要调⽤函数,在代码中给定函数名即可。
3、函数名出现的任何位置,在代码执⾏时,都会被⾃动替换为函数代码。
函数语法
函数常⽤的语法格式有两种:
语法格式⼀
function  f_name  {
...函数体...
}
语法格式⼆
f_name()  {
...函数体...
}
函数的⽣命周期
函数的⽣命周期在被调⽤时开始,返回时终⽌。
其状态返回结果为函数体运⾏的最后⼀条命令的状态结果。当然也可以⾃定义状态返回结果。
⾃定义函数的状态返回值,需要使⽤命令:return,格式如下:
# return [0-255] ;其中 0 代表成功; 1~255 代表失败。
函数执⾏过程中,只要遇到 return 就会终⽌执⾏,即使函数中还有未执⾏完的命令,类似于脚本中的 exit 。⼤家⼀定要注意区分状态返回结果和状态返回值:
命令的返回结果:⽐如使⽤ ls 输出的内容列表
命令的状态返回值:使⽤ # echo $? 进⾏查看。0 代表成功; 1~255 代表失败。
函数返回值
函数的返回值包括两个:
1、函数的执⾏结果返回值
a、使⽤ echo 或者 printf 命令进⾏输出(printf 不会换⾏)
b、函数体中调⽤的命令的执⾏结果
2、函数的退出状态码
a、默认取决于函数体中执⾏的最后⼀条命令的退出状态码
b、⾃定义:return 值
函数参数
函数可以接受函数,在函数体当中,可以使⽤ $1,$2,… 引⽤传递给函数的参数。也可以使⽤ $* 或 $@ 引⽤所有的参数,使⽤ $# 引⽤传递的参数的个数。
在调⽤函数时,在函数后⾯以空⽩符分隔给定参数列表即可,例如: testfunc arg1 arg2 arg3 …
但是⼀定要注意,脚本参数 和 函数参数 是两回事,可以通过以下⽰例进⾏了解。
1、添加10个⽤户,添加⽤户的功能使⽤函数实现,⽤户名作为参数传递给参数。
[root@LeeMumu ~]# bash userAdd10.sh JC
Add user JC1 finished.
Add user JC2 finished.
Add user JC3 finished.
Add user JC4 finished.
Add user JC5 finished.
Add user JC6 finished.
Add user JC7 finished.
Add user JC8 finished.
Add user JC9 finished.
Add user JC10 finished.
[root@LeeMumu ~]# cat userAdd10.sh
#!/bin/bash
#
# 5:user exists
addusers() {
if id $1 &> /dev/null; then
return 5
else
useradd $1
retval=$?
return $retval
fi
}
for i in {1..10}; do
addusers ${1}${i}                  # ${1}${i} 在这⾥对于函数 addusers 来说就是位置参数 $1
retval=$?
if [ $retval -eq 0 ]; then
echo "Add user ${1}${i} finished."
elif [ $retval -eq 5 ]; then
echo "user ${1}${i} exists."
else
echo "Unkown Error."
fi
done
2、编写⼀个脚本,查看 192.168.1.1~192.168.1.254 之间哪些地址可以ping通。
[root@LeeMumu ~]# bash pING.SH
Ping 192.168.1.1 successfully!
Ping 192.168.1.2 successfully!
... ...
[root@LeeMumu ~]# cat pING.SH
#!/bin/bash
#
#
pingtest() {
if ping $1 -c 1 &> /dev/null ; then
echo "Ping $1 successfully!"
else
echo "Ping $1 unsuccessfully!"
fi
}
for i in {1..254}; do
pingtest 192.168.1.$i              # 192.168.1.$i 在这⾥对于函数 pingtest 来说就是位置参数 $1
done
3、打印NN乘法表。
[root@LeeMumu ~]# bash NN1.sh 2
1X1=1
1X2=2 2X2=4
[root@LeeMumu ~]# bash NN1.sh 3
1X1=1
1X2=2 2X2=4
1X3=3 2X3=6 3X3=9
[root@LeeMumu ~]# bash NN1.sh 5
1X1=1
1X2=2 2X2=4
1X3=3 2X3=6 3X3=9
1X4=4 2X4=8 3X4=12 4X4=16
1X5=5 2X5=10 3X5=15 4X5=20 5X5=25
[root@LeeMumu ~]# cat NN1.sh
#!/bin/bash
#
#
NN() {
for ((i=1;i<=$1;i++));do
for ((j=1;j<=i;j++));do
echo -e -n "${j}X${i}=$[${i}*${j}]\t"
done
echo
done
}
NN $1
变量作⽤域
为了便于我们对函数的整体理解,我们在这⼉对 本地变量 和 局部变量 进⾏解释。
1、本地变量
本地变量的作⽤是是运⾏脚本的shell进程的⽣命周期;因此,其作⽤范围为当前shell脚本程序⽂件。脚本执⾏时实在shell⼦进程⾥执⾏,脚本执⾏结束后,变量销毁。
变量赋值:name=value
变量引⽤:${name}, $name
"":变量名会替换为其值;
'':变量名不会替换为其值;
查看变量:set
撤销变量:unset name
(注意:此处⾮变量引⽤;千万不能带 $ 符号,变量引⽤时才需要带 $ 符号)
2、局部变量
局部变量的作⽤域是函数的⽣命周期,在函数结束时被⾃动销毁。
局部变量赋值:local VARIABLE=VALUE
shell脚本返回执行结果函数变量注意事项:
1、函数结束不是脚本结束。
2、函数⾥命令变量时,尽量定义为局部变量。
3、函数⾥⾯可以调⽤本地变量,还可以对本地变量的值进⾏修改,会对⾃⼰脚本变量产⽣影响,所以在函数和主程序不进⾏交互的情
况下,在函数⾥⾯尽量使⽤ local 定义局部变量。
可参考以下博客,有对脚本变量的详细解释:
mp.csdn/mdeditor/95232625#bash_234
函数变量⽰例
通过以下⽰例,⼤家可以加强对函数变量的理解。
1、函数使⽤本地变量,会改变本地变量的值。
[root@LeeMumu ~]# bash fUNCTION1.sh  # 通过结果,可以得知通过调⽤函数改变了本地变量
Function: jerry
Shell: jerry
[root@LeeMumu ~]# cat fUNCTION1.sh
#!/bin/bash
#
name=tom                            # 定义本地变量 name=tom
setname() {
name=jerry                      # 函数⾥定义本地变量
echo "Function: $name"          # echo 函数变量
}
setname                          # 调⽤函数
echo "Shell: $name"              # echo 本地变量
2、函数使⽤本地变量,不会改变本地变量的值。
[root@LeeMumu ~]# bash fUNCTION2.sh  # # 通过结果,可以了解局部变量的作⽤域
Function: jerry
Shell: tom
[root@LeeMumu ~]# cat fUNCTION2.sh
#!/bin/bash
#
name=tom
setname() {
local name=jerry
echo "Function: $name"
}
setname
echo "Shell: $name"
函数递归
函数递归是指函数直接或间接调⽤⾃⾝。
递归⽰例
1、阶乘函数
[root@LeeMumu ~]# bash factTest.sh 1
1
[root@LeeMumu ~]# bash factTest.sh 2
2
[root@LeeMumu ~]# bash factTest.sh 3
6
[root@LeeMumu ~]# bash factTest.sh 11
39916800
[root@LeeMumu ~]# cat factTest.sh
#!/bin/bash
#
#
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ] ;then
echo 1
else
echo $[$1*$(fact $[$1-1])]    # () 代表命令引⽤  [] 代表公式
fi
}
fact $1
2、斐波那契数列
斐波那契数列(Fibonacci sequence),⼜称黄⾦分割数列、因数学家列昂纳多·斐波那契(Leonardod
a Fibonacci)以兔⼦繁殖为例⼦⽽引⼊,故⼜称为“兔⼦数列”,指的是这样⼀个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的⽅法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应⽤,为此,美国数学会从1963年起出版了以《斐波纳契数列季刊》为名的⼀份数学杂志,⽤于专门刊载这⽅⾯的研究成果。
[root@LeeMumu ~]# bash fUNCTION3.sh 9
1 1
2
3 5 8 13 21 34
[root@LeeMumu ~]# cat fUNCTION3.sh
#!/bin/bash
#
fab() {
if [ $1 -eq 1 ]; then
echo -n "1 "
elif [ $1 -eq 2 ]; then
echo -n "1 "
else
echo -n "$[$(fab $[$1-1])+$(fab $[$1-2])] "
fi
}
for i in $(seq 1 $1); do
fab $i
done
echo
函数⽰例
1、给定⼀个⽤户名,取得其⽤户的 id 号和默认的 shell 。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。