一.函数基本知识
与其他编译语言相比,linux shell 也有函数, 如果脚本中有重复的代码,可以使用函数代替。
1.函数基本形式
#!/bin/bash
function name () {
echo "hello everyone !"
}
name #调用函数
function 是关键字,可以加可以不加,不影响脚本执行。
name 是函数名,函数内容写好后需要调用它才能生效,函数名在一个脚本内不能相同,否则会被新函数覆盖。
{ } 标记着函数的开始与结尾,括号内是函数内的命令的集合,即是函数体,函数体不允许空命令,至少需要一条。
[root@foundation77 mnt]# vim fun
[root@foundation77 mnt]# sh fun
hello everyone !
2.函数调用
函数之间允许相互调用,或一个函数调用多个函数,调用时,函数不能在定义前使用。
调用函数,计算70到80的平方和立方
[root@foundation77 mnt]# cat fun
#!/bin/bash
function fun1() { #函数fun1 用于计算方
let "squ=i * i"
echo "square :$squ"
}
function fun2() { #函数fun2 用于计算立方
let "c=i * i * i"
echo "cube :$c"
}
i=70
while [[ "$i" -le "80" ]]
do
echo "$i "
fun1 #脚本中调用函数fun1
fun2 # 调用函数fun2
let "i++"
done
echo "finish"
[root@foundation77 mnt]# sh fun
70
square :4900
cube :343000
71
square :5041
cube :357911
72
square :5184
...
...
80
square :6400
cube :512000
finish
3.调试脚本
bash -x 脚本名 :可以看到脚本的执行顺序,与每一步的运行结果。每次引用函数时,重新回到函数的定义,调用fun1 时返回至fun1,调用fun2 时返回到fun2.
[root@foundation77 mnt]# bash -x fun
+ i=70
+ [[ 70 -le 80 ]]
+ echo '70 '
70
+ fun1
+ let 'squ=i * i'
+ echo 'square :4900'
square :4900
+ fun2
+ let 'c=i * i * i'
+ echo 'cube :343000'
cube :343000
+ let i++
+ [[ 71 -le 80 ]]
+ echo '71 '
71
+ fun1
+ let 'squ=i * i'
+ echo 'square :5041'
square :5041
+ fun2
+ let 'c=i * i * i'
+ echo 'cube :357911'
cube :357911
+ let i++
+ [[ 72 -le 80 ]]
+ echo '72 '
72
+ fun1
+ let 'squ=i * i'
...
...
...
4.函数返回值
有时候脚本执行完后需要返回特定的值来完成后续的操作,这些特定的值就是函数的返回值,函数通过return 返回其退出状态,0表示无错误,1表示有错误。
1)编辑脚本,使输入周一到周五的英文翻译
[root@foundation77 mnt]# cat fun
#!/bin/bash
week(){
echo -n "input:"
echo "$1"
case $1 in
0)
echo "Sunday"
return 0
;;
1)
echo "Monday"
return 0
;;
2)
echo "Tuesday"
return 0
;;
3)
echo "wednesday"
return 0
;;
4)
echo "Thursday"
return 0
;;
5)
echo "Friday"
return 0
;;
6)
echo "saturday"
return 0
;;
*)
return 1
;;
esac
}
if week "$1"
then
echo "right"
else
echo "error"
fi
exit 0
[root@foundation77 mnt]# sh fun 1
input:1
Monday
right
[root@foundation77 mnt]# sh fun 5
input:5
Friday
right
[root@foundation77 mnt]# sh fun 9
input:9
error
[root@foundation77 mnt]#
2) 将函数运行结果返回给脚本
[root@foundation77 mnt]# vim fun
#!/bin/bash
function fun1() {
read -p "Enter a value:" value
echo "doubling the value..."
return $[ $value * 2 ] #返回值的结果
}
fun1
echo "The new value is $?" #输出函数的返回值
[root@foundation77 mnt]# sh fun
Enter a value:9
doubling the value...
The new value is 18
5.函数作用域
shell 编程中,变量的存在方式分为局部变量和全局变量。可以通过关键字local 声明局部变量,局部变量将局限在函数范围内,此外,函数也可以调用函数外的全局变量,如果一个局部变量和一个全局变量名字相同,局部变量会覆盖全局变量。
默认变量为全局变量
编辑脚本测试变量作用域
[root@foundation77 mnt]# vim fun.sh
#!/bin/bash
function fun1(){
a=123 #编辑全局变量a ,赋予初始值为123
echo $a
}
fun1 #调用函数fun1
echo $a #在函数外输全局变量a
function fun2(){
local b=456 #编辑局部变量b ,赋予初始值456
echo $b
}
fun2
echo $b #在函数外测试是否有输出
[root@foundation77 mnt]# sh fun
123
123
456
#输出为空,不再函数外生效
[root@foundation77 mnt]#
6.函数递归
在shell中可以递归调用函数,意思是函数可以间接调用自身,在递归调用中,主调函数又是被调函数。
1)递归求阶乘
[root@foundation77 mnt]# cat fun.sh
#!/bin/bash
function jc(){
local a=$1
if [ "$a" -eq 0 ]
then
c=1
else
let "b=a-1"
jc $b
let "c=$a*$?"
fi
return $c
}
jc $1
echo "factorial of $1 is $?"
exit 0
[root@foundation77 mnt]# sh fun.sh 3
factorial of 3 is 6
[root@foundation77 mnt]# sh fun.sh 5
factorial of 5 is 120
[root@foundation77 mnt]# sh fun.sh 8
factorial of 8 is 128 #?????????
这个脚本在计算较大数值是发生错误,原因是返回值 $? ,它所能传递的最大值是255,如果计算的阶乘结果大于255就不能使用。