shell中的函数
这个系列的文章主要是最近研究安卓源码,发现好多shell和makefile的命令不懂,只能硬着头皮学一波。
1. 函数的定义
shell中定义函数的方式如下:
1 | function function_name(){ |
写一个最简单的例子,新建文件function.sh,内容如下:
1 | !/bin/bash |
这就是一个完整的函数.function关键字可有可无,一般建议写出。
2. 函数的调用
1 | function_name [param...] |
直接执行函数名称即可,后边可以跟一些参数.
现在我们要执行foo
函数,只需要在文件末尾添加foo
即可.,然后执行source function.sh
,可以看到如下输出:
1 | foo |
传入的参数可以在脚本中通过$<index>
的形式来获取.注意0是由调用函数的程序名称占用的,而index是从1开始的,以任意个空格来区分.假如传入的参数少于索引,则索引位置为空.
现在将程序修改如下:
1 | !/bin/bash |
然后执行source function
命令,输出如下:
1 | foo param 0=/bin/bash |
上边关于参数系统提供了一些方法:
$@表示全部的参数,格式是”$1” “$2”…
$也表示全部的参数,格式是”$1 $2 …”
实际中用$@比较多,因为他将参数全部分开了,是数组形式,而$是将所有的参数汇总为了一个参数。
$#表示参数的个数
3. 函数的返回值
shell函数可以写return语句用来返回特定的值,假如未写return语句,默认返回0;函数的返回值范围只能是0~255.
有时候我们需要给定一个函数的返回值来确定函数的执行状态,就需要指定返回的状态码,状态码默认存储在$?
变量中,未写明的话直接返回0.
假如需要返回一个字符串,我们可以使用echo <string>
的形式来返回需要的字符串,$?
变量中存储的仍是函数return的数字,而真正的内容则存储在$(function_name)
中。
修改程序如下,测试返回值:
1 | !/bin/bash |
函数测试了上面的说明语句,foo函数未指定return值,zoo函数输出了两个字符串zoo
和after
,并且返回值为11.执行脚本输出如下:1
2
3
4
5
6
7
8
9foo param 0=/bin/bash
foo param 1=hello
foo param 2=world
foo param 3=
foo return value = 0
zoo
after
zoo return int value = 11
“zoo return string value=zoo after”
可以看到如上所说,并且所有的echo语句都会存储在变量中。
4.局部变量
在shell变量中讲过如何用local
关键字声明一个局部变量。这种声明方式一般用在函数中,保持变量不会被提升到调用函数的环境中,从而不会产生变量污染。
此处讲另一种方式,用()
包裹的变量作用域同样只在括号范围内,不会产生变量污染。那么用括号包裹的命令集会不会是在子进程的shell中执行的呢?验证一下,编写程序如下:1
2
3
4
5
6
7
8
9function parent()
{
echo "this is function process id:$$"
(a=10;echo "this is child fucnton process id:$$")
echo this is a varibale $a
}
echo this is out of function process id: $$
(parent)
很简单的程序,输出结果:1
2
3
4this is out of function process id: 41649
this is function process id:41649
this is child fucnton process id:41649
this is a varibale
进程id一致,且在括号外a变量无值。
所以,括号内声明的变量作用域只在括号内。
函数导出
环境变量可以导出变量,同样函数可以导出,导出后在子进程shell中就可以使用。
1 | function foo(){ |
这样即可。