本章内容:
- 基本的脚本函数
- 返回值
- 在函数中使用变量
- 数组变量和函数
- 函数递归
- 创建库
- 在命令行中使用函数
创建函数
有两种格式可以用来在bash shell脚本中创建函数。第一种格式是采用关键字function,后跟分配给该代码块的函数名:
function name {
command
}
另一种格式:函数名后的圆括号为空,表明正在定义的是一个函数。
name() {
command
}
使用函数
#!/bin/bash
# using a function in a script
function func1{
echo "This is a example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count +1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script"
返回值
bash shell 会把函数当做小型脚本,运行结束时会返回一个退出状态码,有3种不同的方法来为函数生成退出状态码。
第一种方式:利用标准的$?
来决定函数的退出状态码,备注:$?
变量会返回执行的最后一条命令的退出状态码,必须得紧跟在后面
#!/bin/bash
# testing the exit status of a function
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function:"
func1
echo "The exit status is : $?"
第二种方式:使用return
命令 备注:退出状态码必须小于256,任何大于256的值都会返回一个错误值
#!/bin/bash
#using the return command in a function
function db1 {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
db1
echo "The new value is $?"
$./test5
Enter a vlaue:200
doubling the value
The new value is 1
$
第三种方式:使用函数输出
正如同可以将命令的输出保存到shell变量中一样,也可以将函数的输出保存到shell变量中。可以用这种技术来获得任何类型的函数输出,并将其保存到变量中去:
result= `db1`
这个命令会将db1函数的输出赋值给$result这个变量。
#!/bin/bash
#using the echo ri return a value
function db1 {
read -p "Enter a value: " value
echo $[ $value * 20 ]
}
result=`db1`
echo "The new value is $result"
$./tetst5
Enter a value: 200
The new value is 400
$
$./test5
Enter a value: 2000
The new value is 4000
$
向函数传递参数
#!/bin/bash
#passing parameters to a function
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "Adding 10 and 15: "
value=`addem 10 15`
echo $value
echo -n "Let's try adding just one number: "
value=`addem 10`
echo $value
echo -n "Now trying adding no number: "
value=`addem`
echo $value
echo -n "Finally, try adding tree number: "
value=`addem 10 20 30`
echo $value
$./test6
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no number: -1
Finally, try adding tree number: -1
$
由于函数使用特殊参数环境变量作为自己的参数值,它不能直接从脚本的命令行获取传递给脚本的参数值。必须在调用函数是手动将它们传过去。
#!/bin/bash
#trying to access script parameters inside a function
function func7 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=`func7 $1 $2`
echo "The result is $value"
else
echo "The Usage: badtest1 a b"
fi
$
$./test7
The Usage: badtest1 a b
$./test7 10 15
The result is 150
$
在函数中处理变量
函数会用两种类型的变量:
全局变量
-
局部变量
全局变量
是在shell脚本中任何地方都有效的变量。如果你在函数中定义了一个全局变量,你可以在脚本的主体部分读取它的值。默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可以在函数内正常访问:
#!/bin/bash
#using a global variable to pass a value
function db1 {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is:$value"
#$value 变量是在函数外定义的,并在函数外被赋值了。当db1函数被调用时,变量及其值在函数中依然有效。如果变量在函数中被赋予了新的值,那么在脚本中引用该变量是,新值依然有效。
#!/bin/bash
#demonstrating a bad use of variables
function func1 {
temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
$./badtest2
The result is 22
temp is larger
$
#由于$temp变量在函数中用到了,它的值在脚本中使用,产生了一个意想不到的结果。此时如果需要避免这个问题,得需要使用局部变量
局部变量
在函数内部使用的任何变量都可以被声明称局部变量,只要在变量声明的前面加上local
关键字就可以了:
local temp
#local 关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名称的变量,那么shell将会保持这两个变量的值是分离的。那么你就能很轻松地让函数变量和脚本变量分离开来,只共用想共用的:
#!/bin/bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
$
$./test9
The result is 22
temp is smaller
$
#现在在func1函数中使用$temp变量时,并不影响在主体脚本中赋给$temp变量的值
数组变量和函数
- 向函数传数组参数
#!/bin/bash
#tring to pass an array variable
function testit {
echo "The parameters are: $@"
thisarray=$1
echo "The received array is ${thisarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is : ${myarray[*]}"
testit $myarray
$./badtest3
The original arry is: 1 2 3 4 5
The parameters are: 1
./badtest3: thisarray[*]: bad array subscript
The received array is
$
#如果你试图将该数组当成一个函数参数,函数只会取数组变量的第一个值。
解决的方法,你可以将所有的参数重组到新的数组变量中
#!/bin/bash
# array variable to function test
function testit {
local newarray
newarray=(`echo $@`)
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
$./test10
The original array is 1 2 3 4 5
The new array is 1 2 3 4 5
$
- 从函数返回数组
#!/bin/bash
#returning an array value
function arrayblr {
local origarray
local newarray
local elements
local i
origarray=(`echo $@`)
newarray=(`echo $@`)
elements=$( $# - 1 )
for (( i=0; i <= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i] * 2} ]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=`echo ${myarray[*]}`
result=(`echo $arg1`)
echo "The newarray is $result[*]"
$
$./test12
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10
- 函数递归
#!/bin/bash
#using recursion
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=`factorial $temp`
echo $[ $result * $1 ]
fi
}
read -p "Enter a value: " value
result=`factorial $value`
echo "The factorial of $value is: $result"
- 创建库
#my script functions
function addem {
echo $[ $1 + $2 ]
}
function multem {
echo $[ $1 * $2 ]
}
#!/bin/bash
#using a library file
source ./myfuncs
#. ./myfuncs source的快捷别名, 点操作符
value1=10
value2=5
result1=`addem $value1 $value2`
result2=`multem $value1 $value2`
echo "The result of addem them is: $result1"
echo "The result of multem them is: $result2"
$./test14
The result of addem them is: 15
The result of multem them is: 50
$