1.基本的脚本函数
1.1创建函数:
name(){
Command;
}
在调用函数时,bash shell会按命令在函数中出现的顺序依次执行,就像在普通脚本中一样。
1.2使用函数:
在行中指定函数名就行了。
同样的,如果再函数被定义前使用,则是非法的。
如果重定义了函数,新定义会覆盖原来函数的定义。
1.3 返回值
Bash shell 会把函数当作一个小型脚本,运行结束时会返回一个退出状态码。
(1)默认退出状态码
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量‘$?’来确定函数的退出状态码。
(2)使用return命令
Bash shell使用return命令来退出函数并返回特定的退出状态码。
return命令允许指定一个整数值来定义函数的退出状态码。
(3)使用函数输出
可以将函数的输出保存到变量中,以便后续使用。
如:Result=`fun1`
2.在函数中使用变量
2.1 向函数传递参数
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。
如:函数名会在‘$0’变量中定义,函数命令行上的任何参数都会通过‘$1’,‘$2’等定义。也可以通过特殊变量‘$#’来判断传给函数的参数数目。
2.2 在函数中处理变量
给shell脚本程序员带来麻烦的原因之一就是变量的作用域。作用域是变量可见的区域。函数中定义的变量与普通变量的作用域不同。
函数可使用两种类型的变量:
- 全局变量;
- 局部变量;
(1)全局变量
全局变量是在shell脚本中任何地方都有效的变量。
如果在脚本的主体部分定义了一个全局变量,那么在函数内也可以读取它。反之,如果在函数内部定义了一个全局变量,也可以在脚本的主体中调用它。
默认情况下,在脚本中定义的任何变量都是全局变量。在函数外定义的变量可以在函数内正常访问。
(2)局部变量
函数内部使用的任何变量都可以被声明成局部变量。要实现这一点,只要在变量声明前面加上local关键字即可。
也可以在变量赋值语句中使用local关键字。
如:local temp=$[ $value + 5 ]
Local关键字保证了变量只局限在该函数中。
3.数组变量和函数
3.1向函数传数组参数
特殊变量列表:
变量 | 含义 |
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
$* 和 $@ 的区别:
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
例:
myarray=(1 2 3 4 5)
testfun()
{
local newarray
newarray=('echo "$@"')
echo "The new array is : ${newarray[*]}"
}
testfun $(myarray[*])
用$myarray变量来保存所有数组元素,然后将它们都放在函数的命令行上。该函数从命令行参数中重建数组变量。
3.2 从函数返回数组
函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。
#!/bin/bash
# returning an array value
arraydblr()
{
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)
arg1=$(echo ${myarray[*]})
result=$($(arraydblr $arg1))
echo "The new array is : ${result[*]}"
运行上面该脚本后输出:The new array is : 2 4 6 8 10
说明:脚本中用$arg1变量将数组值传给arraydblr函数。函数再将该数组重组到新的数组变量中,生成该输出数组变量中的一个副本。然后对数组元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。函数中使用echo语句来输出每个数组元素的值。
4.函数递归
局部函数变量的一个特性是自成体系。除了从脚本命令行处获得的变量,自成体系的函数不需要使用任何外部资源。
这个特性使得函数可以递归的调用,即函数可以调用自己来得到结果。
通常递归函数都有一个最终可以迭代到的基准值。
5.创建函数库文件
!bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。
首先创建一个包含脚本中所需函数的公用库文件。
如:有一个叫myfuncs的库文件,它定义了3个简单的函数:
#my script functions
addem()
{
echo $[ $1 + $2 ]
}
multem()
{
echo $[ $1 * $2 ]
}
divem()
{
if [ $2 -ne 0 ];then
echo $[ $1 / $2 ]
else
echo -1
fi
}
下一步是在用到这些函数的脚本文件中包含myfuncs库文件。
使用函数库的关键在于source命令。
source命令会在当前shell上下文中执行命令,而不是创建一个新的shell。可以用source命令来在shell脚本中运行库文件脚本。这样脚本就可以使用库中的函数了。
source命令也可以用‘.’操作符替代。要在shell脚本中运行myfuncs库文件,只需添加如下一行:
source ./myfuncs (或: . ./myfuncs)
上例中假定myfuncs库文件和shell脚本位于同一目录,如果不是,需要使用相应路径访问该文件。