从这一章开始,我们将建设一个项目。这个项目的目的是为了了解怎样使用各种各样的 shell 功能来 创建程序,更重要的是,创建好程序。
我们将要编写的程序是一个报告生成器。它会显示系统的各种统计数据和它的状态,并将产生 HTML 格式的报告, 所以我们能通过网络浏览器,比如说 Firefox 或者 Konqueror,来查看这个报告。
cd ~/bin/
touch sys_info_page.bash
向文件中输入以下内容:
#!/bin/bash
# Program to output a system information page
echo ""
echo " "
echo " Page Title "
echo " "
echo " "
echo " Page body."
echo " "
echo ""
程序包含了一条注释和一系列的 echo 命令,每个命令负责输出一行文本。保存文件之后,我们将让它成为可执行文件,再尝试运行它:
chmod 755 sys_info_page.bash
sys_info_page
当程序运行的时候,我们应该看到 HTML 文本在屏幕上显示出来,因为脚本中的 echo 命令会将输出 发送到标准输出。我们再次运行这个程序,把程序的输出重定向到文件 sys_info_page.html 中, 从而我们可以通过网络浏览器来查看输出结果:
firefox sys_info_page.html
或者输入:
open sys_info_page.html
实际上,我们可以把所有的 echo 命令结合成一个 echo 命令,当然 这样能更容易地添加更多的文本行到程序的输出中。那么,把我们的程序修改为:
#!/bin/bash
# Program to output a system information page
echo "
Page Title
Page body.
"
当我们想要修改文件中多个相同的地方,就可以给赋值为一个变,一般在shell中,变量是用大写字母表示。
向文件中添加一个标题,用TITLE变量表示:TITLE=”System Information Report For $HOSTNAME”, 将文件中内容更改如下:
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
echo "
$TITLE
$TITLE
"
在文件中引用一个变量,用$TITLE表示,在变量名的前边加一个美元符号。
输出结果如下:
注意在赋值过程中,变量名、等号和变量值之间必须没有空格。那么,这些值由什么组成呢? 可以展开成字符串的任意值:
可以在同一行中对多个变量赋值:
在参数展开过程中,变量名可能被花括号 “{}” 包围着。由于变量名周围的上下文,其变得不明确的情况下, 这会很有帮助。这里,我们试图把一个文件名从 myfile 改为 myfile1,使用一个变量:
mv $filename $filename1
,这种尝试失败了,因为 shell 把 mv 命令的第二个参数解释为一个新的(并且空的)变量。通过mv $filename ${filename}1
,这种方法 可以解决这个问题。通过添加花括号,shell 不再把末尾的1解释为变量名的一部分。
我们已经知道了两种不同的文本输出方法,两种方法都使用了 echo 命令。还有第三种方法,叫做 here document 或者 here script。一个 here document 是另外一种 I/O 重定向形式,我们 在脚本文件中嵌入正文文本,然后把它发送给一个命令的标准输入。它这样工作:
command << token
text
token
这里的 command 是一个可以接受标准输入的命令名,token 是一个用来指示嵌入文本结束的字符串。 我们将修改我们的脚本,来使用一个 here document:
#!/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_
$TITLE
$TITLE
$TIME_STAMP
_EOF_
取代 echo 命令,现在我们的脚本使用 cat 命令和一个 here document。这个字符串EOF(意思是“文件结尾”, 一个常见用法)被选作为 token,并标志着嵌入文本的结尾。注意这个 token 必须在一行中单独出现,并且文本行中 没有末尾的空格。
那么使用一个 here document 的优点是什么呢?它很大程度上和 echo 一样,除了默认情况下,here documents 中的单引号和双引号会失去它们在 shell 中的特殊含义。这里有一个命令中的例子:
foo="some text"
cat << _EOF_
$foo
"$foo"
'$foo'
\$foo
_EOF_
some text
"some text"
'some text'
$foo
正如我们所见到的,shell 根本没有注意到引号。它把它们看作是普通的字符。这就允许我们 在一个 here document 中可以随意的嵌入引号。对于我们的报告程序来说,这将是非常方便的。