shell中的函数
1.定义与使用函数
- 在shell中,函数必须在使用前定义,有两种风格的定义函数的方法
function myfunc1 {
...
}
myfunc2() {
...
}
- 调用并使用函数很简单,直接写名字即可。注意只能在定义之后调用函数
myfunc1
myfunc2
2.函数的参数与变量
- 函数也可以被传参,如下。值得注意的是,由于函数体内将
$0 $1 $2
等识别为函数的参数,所以函数体内无法用$0 $1 $2
等获得脚本参数。如果函数体内实在要获得脚本参数,则可以在调用函数时,将脚本参数原封不动的传给函数
myfunc1() {
}
myfunc1 1 $var
- 普通变量可以在函数内、外随便用,反正是全局的。假如我们想实现函数私有的变量怎么办?只需在函数体内定义变量,并用
local
修饰,这样变量的作用域就被限制在了函数体内部
3.函数的退出
- 函数运行结束时会返回一个返回值,它的值其实是函数中最后一条命令的返回值,所以,最后一条命令前面那些命令的执行成功与否,我们是不得而知的
- 相对于默认的函数返回值,更推荐使用return命令来自定义返回值,其值可以由我们自己定义
func1() {
...
return $[ $var * 2 ]
}
- 获取函数返回值有两种方式,如下。推荐使用变量方式来获取
func1
echo $?
func1
ret=`func1`
4.shell函数库的使用和函数作用域
- 函数的作用域和全局环境变量是相同的,即“父亲传儿子”
- 所谓shell函数库,就是定义了一堆函数的脚本。比如a.sh中定义了很多函数,其他脚本b.sh、c.sh去调用那些函数,那么可以称a.sh为函数库。但是问题来了,在控制台中先执行a.sh,再执行b.sh,发现b.sh识别不到a.sh函数库
./a.sh
./b.sh
- 其实原因很简单,是函数的作用域造成的,b.sh是a.sh同级的shell,并不是其子孙,所以a.sh中的函数作用域覆盖不到b.sh
控制台shell
|__a.sh(函数作用域从这里开始)
| |__xxx
|__b.sh
- 解决方法是使用source命令来执行a.sh,将它在当前shell的上下文中执行,即将函数作用域的起始位置改为它的父亲,这样它的同级shell也能被作用域所覆盖了
控制台shell(函数作用域从这里开始)
|__a.sh____↑
| |__xxx
|__b.sh