shell脚本学习指南-入门
##1.1 为什么使用shell脚本
使用脚本编程语言的好处是,它们多半运行比编译型语言还高的层次,能够轻易处理文件与目录之类的对象。缺点是:它的效率通常不如编译型语言。因为shell似乎是各UNIX系统之间的通用的功能,并且经过了POSIX的标准化。因此,shell脚本只要“用心写”一次,即可应用到很多系统上。因此,之所以使用shell脚本基于:
-
简单性,shell 是一个高级语言。通过它,你可以简洁地表达复杂的操作。
-
可移植性, 使用POSIX所定义的功能,可以做到脚本无须修改就可在不同的系统上执行。
-
开发容易,可以在短时间内完成一个功能强大又好用的脚本。
##1.2 基本IO重定向
许多UNIX程序,默认情况下,它们会读取标准输入、写入标准输出、并将错误信息传递到标准错误输出。这类程序叫做过滤器,你马上就会知道这么叫的原因。默认的标准输入、标准输出以及标准错误输出都是终端,这点可通过cat程序得知:
prompt> cat
now is the time
now is the time
for all good men
for all good men
to come to the aid of their country
to come to the aid of their country
^D Ctrl-D,文件结尾
你可呢个想知道,是谁替执行中的程序初始化标准输入、输出及错误输出呢?毕竟,总该有人来替执行中的程序代开这些文件,甚至是让用户在登陆后能够看到交互的shell界面。
答案就是在你登陆时,UNIX便将默认的标准输入、输出及错误输出安排成你的终端。I/O重定向就是你通过与终端交互,或是在shell脚本里设置,重新安排从哪里输入或输出到哪里。
###1.2.1 重定向与管道
shell提供了数种语法标记,可用来改变默认I/O的来源端与目的端。此处会先介绍基本用法,让我们由浅入深地依次介绍如下:
以 < 改变标准输入
program < file可将program的标准输入改为file:
tr -d '\r' < doc-file.txt
以 > 改变标准输出
program > file可将program的标准输出改为file:
tr -d '\r' < doc-file.txt > UNIX-file.txt
> 重定向符在目的文件不存在时,会新建一个。然而,如果目的文件已经存在,它就会被覆盖掉;原本的数据会丢失。
以 » 附加到文件
program >> file可将program的标准输出附加到file结尾处:
tr -d '\r' < doc-file.txt >> UNIX-file.txt
若同> ,如果目的文件不存在时,>>会新建一个。然而,如果目的文件已经存在,它不会覆盖原本的数据,而是将程序所产生的数据附加到文件结尾处:
for f in dos-file*.txt
do
tr -d '\r' < $f >> big-UNIX-file.txt
done
以 | 建立管道
program1 | program2 可将program1的标准输出修改为program2的标准输入。虽然 < 与 >可以将输入与输出连接到文件,不过管道可以把两个以上的执行中的程序衔接在一起。第一个程序的标准输出作为第二个程序的标准输入,这么做的好处是,管道可以使执行速度比使用临时文件的程序快上十倍。使用UNIX工具程序时,不妨将数据想象成水管里的水,未经处理的水,将流向净水厂,经过各类过滤器的处理,最后产生适合人类饮用的水。
同样编写脚本时,你通常已有某种输入格式定义下的原始数据,而需要处理这些数据后产生结果。从原始的数据开始,然后构造一条管道,一步一步地,管道中的每个阶段都会让数据更接近结果。我们可以把 < 与 > 想象成数据的漏斗---------数据从大的一端进入,由小的一端出来。
###1.2.2 特殊文件:/dev/null与/dev/tty
UNIX系统提供了两个对shell编程特别有用的特殊文件。第一个文件/dev/null,就是大家所熟知的位桶。传送至此文件的数据会被系统丢掉。也就是说,当程序将数据写到此文件时,会认为它已成功完成写入数据操作,但实际上什么事都没有做。如果你需要的是命令的推出状态,而非它的输出,此功能会很有用。例如,测试一个文件是否包含某个模式(pattern):
if grep pattern myfile > /dev/null
then
... find the pattern
else
... not find the pattern
相对地,读取/dev/null则会立即返回文件结束符号(end of file)。
另一个特殊文件为/dev/tty。当程序打开此文件时,UNIX会自动重定向到一个终端或串行端口,也可能是一个通过网络与窗口登陆的伪终端再与程序结合。这在程序必须读入人工输入时特别有用。此外用它来产生错误信息也很方便,只是比较少人这么做: