一.函數基本知識
與其他編譯語言相比,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就不能使用。