把那些在脚本中重复出现并且没有任何改变的代码,封装起来,在适当的场景中调用执行。程序员将这种被封装起来的代码称为功能体,或者叫模块,也称为函数。这样看来是不是和循环类似,循环也是为了方便去多次执行一堆代码,而函数是将一堆代码写在一起,起一个名字,然后在需要这堆代码的时候只需要写上函数的名字即可。在shell脚本编程中,函数是由若干条shell命令组成的语句块,函数里面的内容和shell程序形式上是一致的。不同之处就是,shell代码可以直接被执行,而函数中的内容,不能独立执行,只有被调用的时候才执行。比如:

#!/bin/bash
out(){
echo "123"
}
[root@localhost class]# bash hanshu 
[root@localhost class]#

在上面这个例子中,我在脚本中写入了一个函数,但是没有去调用它,所以在执行这个脚本后,没有任何的输出。接下来说一下如何去定义一个函数。

函数是由函数名称和函数体(能够实现独立功能的shell语句块)两部分组成,格式为:

function func_name {
函数体
}

或者:

func_name() {
函数体
}

注意:函数名和()之间不能加空白字符

这两种不同的定义方法都可以定义函数,不同点在于函数名字前的“function”这个命令,这个命令可有可无。定义函数不一定非得在脚本中定义,还可以在交互式环境下定义,比如在命令行中直接输入函数名来定义,例如:

[root@localhost class]# out()
> {
> echo "123"
> }
[root@localhost class]# out
123

在定义的时候,一个函数以“{”开始,以“}”结束,在定义完成后就可以直接使用名字来调用这个函数。可以使用“set”命令来查看自己定义的和系统内已经存在的函数,使用unset命令可以撤销已经定义的函数。值得注意的是在当前shell内定义的函数只能在当前shell中使用,一旦关闭,那么定义的函数就会消失。同理,在脚本中定义的函数会随着脚本的关闭而消失,比如:

testEcho(){
echo "执行了show函数"
}
[root@localhost class]# bash testfunction 
[root@localhost class]# testEcho
bash: testEcho: 未找到命令...
[root@localhost class]# source testfunction 
[root@localhost class]# testEcho
执行了show函数


在这个例子中我们可以看到,当使用bash执行脚本之后在脚本内加载了“testEcho”这个函数但是随着这个脚本的关闭,再执行这个函数的时候就会报错了,而之后我又使用了“source”命令来执行这个脚本之后,在当前shell内就可以使用脚本内定义的函数了。这是一种在当前shell中使用脚本内函数的方法。

像命令一样,函数的执行也会有一个返回值,分为以下两种:

第一种是函数的执行结果的返回值,例如在函数体中某些命令输出的结果;

第二种是函数的状态返回值:

1.函数中最后一条命令的执行状态返回值;

2.自定义退出状态码:

return [n]

n:0-255 (1 2 127尽可能不使用)

0: 表示无错误返回

1-255:有错误返回

注意:跟其他编程语言一样,只要函数在执行时,遇到了return命令,不管函数中的命令语句是否全部执行完成,立刻退出函数。一个函数从被调用开始,直到遇到return命令或全部的语句执行完才终止。

在调用函数的时候我们也可以将一些参数传入进去,方法是在调用函数的时候直接在函数名后头写上参数,使用空格隔开,比如:func_name arg1 arg2 ...。在函数体中,可以使用$1,$2,..等位置变量来调用外部调用此函数时为此函数提供的参数,和脚本一样,还可以使用$*或$@的方式引用所有位置参数或者使用$#计算为函数传递的参数个数。举例如下:

#!/bin/bash
out(){
echo $@
}
out a b c #在这里调用函数,并将“a b c ”作为参数传到函数中
[root@localhost class]# bash funcdiaoyong
a b c