购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5 函数

在Shell程序中允许使用函数,函数实际上也是由若干条Shell命令组成的,因此它与Shell程序在形式上是相似的,不同的是它不是一个单独的进程,而是Shell程序的一部分。函数由两部分组成:函数名和函数体。

2.5.1 定义函数

Shell函数定义的一般格式为:

也可以在函数名前加上Shell关键字function用以修饰函数,如下所示:

函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中。函数不必包含很多语句或命令,甚至可以只包含一个echo语句,这取决于编程者。

归纳起来,Shell函数的定义和使用可分为以下三种情况:

● 在Shell终端的交互式环境下定义和使用函数;

● 在Shell脚本程序中定义和使用函数,使其成为Shell程序的一部分;

● 在一个单独的文件中定义函数,Shell程序调用该函数。

说明

Shell函数和Shell程序比较相似,它们的区别在于:Shell程序在子Shell中运行,而Shell函数在当前Shell中运行。因此在当前Shell中可以看到Shell函数对变量的修改情况。

另外,在函数中也可以使用Shell的各种变量,最大的好处是,可以使用系统变量$1、$2、$3……$9向函数传递参数。函数正常执行到函数末尾,然后返回到脚本中调用函数的部分。使用return返回脚本中函数调用的下一条语句,可以带有返回值,“return 0”表示无错误,“return 1”表示出错返回。因此,可以对函数的返回值进行处理,以判断子程序是否成功执行。

2.5.2 交互式Shell中定义和使用函数

最简单的方式是直接在Shell终端的交互式环境中定义和使用函数,如在Shell终端中输入下面的命令,定义一个名为dir的函数:

定义该函数后,若在Shell终端中输入dir,则显示结果同ls -l的命令一致:

该dir函数将一直保留到用户从系统中退出,或执行了如下所示的unset命令:

unset命令用于注销在Shell交互式环境中定义的函数。

2.5.3 Shell脚本中定义和使用函数

Shell程序中的函数必须在使用前进行定义,因此一般将函数的定义放在脚本开始的部分,当Shell解释器首次发现它后才能正确调用该函数。调用函数仅使用函数名即可。

在程序2.4中,试验了一个根据系统当前时间输出问候语的例子,这里使用函数调用的形式来重写程序2.4,使其在子程序中负责输出问候语,代码如程序2.12所示。

【程序2.12】根据系统时间输出问候语:greeting_again.sh。

使用chmod命令修改文件的执行权限:

运行程序,输出结果如下:

可以看到,上例中的被调用函数均定义于脚本顶部,在脚本中使用该函数时只需调用函数名即可。而关于函数调用及嵌套调用的规则及原理,与其他高级程序设计语言也是如出一辙,此处不再一一讲解。

2.5.4 将函数定义在单独的文件中

也可以将函数定义在一个单独的Shell脚本文件中,如将经常使用的函数存入函数文件,然后将函数文件载入Shell。一旦函数文件载入Shell,就可以在命令行或脚本中像输入普通命令一样通过函数名来调用该函数。

保存函数的文件名可任意选取,但最好保持函数功能、文件名、函数名一致,这样便于记忆(本来Linux下就有成百上千个命令,就不要再给自己增加额外的负担了)。例如,试写一个与find命令功能类似的函数myfind,代码如程序2.13所示。首先,使用touch命令创建一个普通的文本文件myfind,函数名也为myfind:

【程序2.13】试写一个与find命令功能类似的函数myfind。

文件创建完毕后,需要将函数文件载入Shell中,载入文件的格式为:

注意,是“<点><空格><文件名>”的格式,中间的空格不能省略。下面将myfind函数载入Shell:

现在,myfind文件应该已经载入Shell。如果仍有错误,则应仔细检查是否输入了完整的路径名。然后,可以使用set命令检查函数是否已经成功载入,set命令将在Shell中显示所有已经载入的函数,包括系统中的环境变量。

要执行函数,简单地输入函数名即可,就像使用Shell的内部命令一样(下面简单列出了读者Linux系统中log文件的部分搜索结果):

使用unset命令,可以将函数从Shell中卸载,如使用下面的命令:

此时再使用set命令查看当前Shell中已载入的函数时,会发现已经没有myfind这个函数了。当然,再次输入myfind命令,系统会提示“命令未找到”。

最后,若需改动函数,则应首先使用unset命令从Shell中删除函数,改动完毕后,再重新载入此文件。 Rg/er8X+o/lt062c8BjuidihBcajtk1XevR3AVFNTMUJwxvdCqx0R186E5RxAMWz

点击中间区域
呼出菜单
上一章
目录
下一章
×