自顶向下设计
摘要:先确定上层步骤,然后再逐步细化这些步骤的过程被称为自顶向下设计。这种技巧允许我们把庞大而复杂的任务分割为许多小而简单的任务。自顶向下设计是一种常见的程序设计方法,尤其适合 shell 编程。在这一章中,我们将使用自顶向下的设计方法来进一步开发我们的报告产生器脚本。
Shell函数
我们在上一节输出网页的例子里添加一些东西,包括:
- 系统正常运行时间和负载。这是自上次关机或重启之后系统的运行时间,以及在几个时间间隔内当前运行在处理中的平均任务量。
- 磁盘空间。系统中存储设备的总使用量。
- 家目录空间。每个用户所使用的存储空间使用量。
如果对于每一个任务,我们都有相应的命令,那么通过命令替换,我们就能很容易地把它们添加到我们的脚本中:
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME, by $USER"
cat << _EOF_ <HTML> <HEAD> <TITLE>$TITLE</TITLE> </HEAD> <BODY> <H1>$TITLE</H1> <P>$TIME_STAMP</P> $(report_uptime) $(report_disk_space) $(report_home_space) </BODY> </HTML> _EOF_
我们能够用两种方法来创建这些额外的命令。我们可以分别编写三个脚本,并把它们放置到环境变量 PATH 所列出的目录下,或者我们也可以把这些脚本作为 shell 函数嵌入到我们的程序中。我们之前已经提到过,shell 函数是位于其它脚本中的“微脚本”,作为自主程序。Shell函数有两种语法形式:
function name {
commands
return
}
和
name () {
commands
return
}
这里的 name 是函数名,commands 是一系列包含在函数中的命令。
两种形式是等价的,可以交替使用。
下面我们将查看一个说明 shell 函数使用方法的脚本:
1 #!/bin/bash
2
3 # Shell function demo
4
5 function funct {
6 echo "Step 2"
7 return
8 }
9
10 # Main program starts here
11
12 echo "Step 1"
13 funct
14 echo "Step 3"
随着 shell 读取这个脚本,它会跳过第 1 行到第 11 行的代码,因为这些文本行由注释和函数定义组成。从第 12 行代码开始执行,有一个 echo 命令。第 13 行会调用 shell 函数 funct,然后 shell 会执行这个函数,就如执行其它命令一样。这样程序控制权会转移到第六行,执行第二个 echo 命令。然后再执行第 7 行。这个 return 命令终止这个函数,并把控制权交给函数调用之后的代码(第 14 行),从而执行最后一个 echo 命令。
注意为了使函数调用被识别出是 shell函数,而不是被解释为外部程序的名字,在脚本中 shell 函数定义必须出现在函数调用之前。
Shell 函数的命名规则和变量一样。一个函数必须至少包含一条命令。
局部变量
全局变量在整个程序中保持存在。局部变量只能在定义它们的 shell 函数中使用,并且一旦 shell函数执行完毕,它们就不存在了。
通过在变量名之前加上单词 local
,来定义局部变量。
你的.bashrc 文件中的 shell 函数
Shell 函数完美地替代了别名,并且实际上是创建个人所用的小命令的首选方法。别名非常局限于命令的种类和它们支持的 shell 功能,然而 shell 函数允许任何可以编写脚本的东西。
总结归纳
这一章中,我们介绍了一种常见的程序设计方法,叫做自顶向下设计,并且我们知道了怎样使用 shell 函数按照要求来完成逐步细化的任务。我们也知道了怎样使用局部变量使 shell 函数独立于其它函数,以及其所在程序的其它部分。这就有可能使 shell 函数以可移植的方式编写,并且能够重复使用,通过把它们放置到多个程序中;节省了大量的时间。