可以在shell中定义函数。如果你想编写大型的shell脚本程序,你会想到用它们来构造自己的代码。
作为另一种选择,你可以把一个大型的脚本程序分成许多小一点的脚本程序,让每个脚本完成一个小任务。但这种做法有几个缺点:在一个脚本程序中执行另外一个脚本程序要比执行一个函数慢得多;返回执行结果变得更加困难,而且可能存在非常多的小脚本。当准备将一个大型脚本程序分解为一组小脚本的时候,你应该把自己的脚本程序中可以明显的单独存在的最小部分作为衡量的尺度。
如果你对使用 shell来编写大型程序感到恐惧,请记住,自由软件基金会FSF的autoconf程序和多个Linux软件包的安装程序就是shell脚本程序。你总是可以保证在Linux系统中有一个基本的shell。通常情况下,如果没有/bin/sh,Linux和UNIX系统根本就不能启动,更不用说允许用户登录系统了,所以你应该可以确信绝大多数的UNIX和Linux系统都会提供一个能够解释并运行你的脚本程序的shell。
要定义一个shell函数,我们只需简单地写出它的名字,然后是一对空括号,再把有关的语句放在一对花括号中,如下所示:
![]()
实验:简单的函数
我们从一个非常简单的函数开始:

运行这个脚本程序会显示如下的输出信息:
![]()
实验解析
这个脚本程序还是从自己的顶部开始执行,这一点与其他脚本程序没什么分别。但当它遇见 foo(){结构时,它知道定义了一个名为foo的函数。它会记住foo代表着一个函数并从}字符之后的位置继续执行。当执行到单独的行foo时, shell就知道应该去执行刚才定义的函数了,当这个函数执行完毕以后,执行过程会返回到调用foo函数的那条语句的后面继续执行。
你必须在调用一个函数之前先对它进行定义,这有点像Pascal语言里函数必须先于调用而被定义的概念,只是在shell中不存在前向声明。但这并不会成为什么问题,因为所有脚本程序都是从顶部开始执行,所以只要简单地把所有函数定义都放在任何一个函数调用之前就可以保证所有的函数在被调用之前就被定义了。
当一个函数被调用时,脚本程序的位置参数$*、$@、$#、$1、$2等会被替换为函数的参数。这也是你读取传递给函数的参数的办法。当函数执行完毕后,这些参数会恢复为它们先前的值。
一些老版本的shell在函数执行之后可能不会恢复位置参数的值。所以如果你想让自己的脚本程序具备可移植性,就最好不要依赖这一行为。
我们可以通过return命令让函数返回数字值。让函数返回字符串值的常用方法是让函数将字符串保存在一个变量中,而该变量应该可以在函数结束之后被使用。此外,你还可以echo一个字符串并捕获其结果,如下所示:

