




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第21章 Shell编程,无法想象没有Shell的Linux会是什么样子。从一开始,Linux就是黑客们的玩具,在Linux的世界里,没有什么是不可控的。如果想要成为一名高级Linux用户,那么Shell编程是必须跨过的一道坎。本章将从正则表达式开始,逐步介绍Shell编程的基本知识。这些内容对于没有任何编程经验的读者可能有点困难,不过想一想将要接触到的激动人心的技术,请打起精神来!,21.1 正则表达式,正则表达式广泛地应用在各种脚本编程语言中,包括Perl、PHP、Ruby等等。Linux的各种编程工具也大量采用了正则表达式。可以说,有字符串处理的地方,就有正则表达式的身影。本节简要介绍正
2、则表达式的基本语法。在开始之前,首先关心一下正则表达式的“定义”。,21.1.1 什么是正则表达式?,“正则表达式(regexps)”这个词背后的历史似乎很难考证。一直以来,这个说法被人们广泛应用,没有人关心或许也没有必要关心它是怎么来的。在很多时候,“正则表达式”又被称作“模式”,所以千万别被这两件不同的外衣搞糊涂了,至少在Linux中,“模式”和“正则表达式”讲的是一回事情。 那么究竟什么是正则表达式?简单地说,这是一组对正在查找的文本的描述。考虑一个生活中的例子,老师对调皮捣蛋的学生说:“把单词表中a开头、t结尾的单词抄写10遍交给我。”那么对于正在抄写单词的学生而言,“a开头、t结尾的
3、单词”就是“对正在查找的文本的描述”。同样可以告诉Shell,“把当前目录下所有以e结尾的文件名列出来”,这是正则表达式擅长做的事情。,21.1.2 不同风格的正则表达式,正则表达式是一种概念。在此基础上,人们充分发挥想象力,发明了各种风格的正则表达式。在这个领域,至今没有什么标准可言,不同的软件和编程语言支持不同风格的表达式写法,也难怪刚刚接触正则表达式的用户会因此感到困惑。 目前在GNU/Linux中,有两套库可用于正则表达式编程:POSIX库和PCRE库。前者是Linux自带的正则表达式库;后者是Perl的正则表达式库。从功能上看,PCRE风格的正则表达式更强大一些,但也更难掌握一些。本
4、节选择POSIX风格的正则表达式作为讨论对象,POSIX库不需要额外安装,直接使用即可。在工具方面,本节所有的示例都在egrep工具中测试通过,参考5.5.8节了解egrep的详细信息。,21.1.3 快速上手:在字典中查找单词,现在来考虑本节开始的那个例子。老师要求抄写单词表中“a开头、t结尾”的单词,学生现在很想知道他究竟要花多少时间在这个作业上。/usr/share/dict/words中包含了多达98568个单词,看起来无论老师所说的“单词表”是什么,Linux给出的估算只多不少: $ egrep a.*t$ /usr/share/dict/words#列出单词表中a开头t结尾的所有单
5、词 abaft abandonment abasement abatement abbot abduct aberrant abet abhorrent,21.1.4 字符集和单词,在正则表达式中,句点“.”用于匹配除换行符之外的任意一个字符。下面这条正则表达式可以匹配诸如“cat”、“sat”、“bat”这样的字符串: .at “.”能够匹配的字符范围是最大的。上面这个正则表达式还能够匹配“#at”、“at”、“_at”这样的字符串。很多时候,需要缩小选择范围使匹配更为精确。为了限定“at”前的那个字符只能是小写字母,可以这样写正则表达式: a-zat,21.1.5 字符类,除了字符集,PO
6、SIX风格的正则表达式还提供了预定义字符类来匹配某些特定的字符。例如,下面的命令列出文件中所有以大写字母开头,以小写t结尾的行: $ egrep :upper:t$ words At It Lt Mt Pt St,21.1.6 位置匹配,字符“”和“$”分别用于匹配行首和行尾。下面这条正则表达式用于匹配所有以“a”开头、“t”结尾、“a”和“t”之间包含一个小写字母的行: aa-zt$ “”和“$”不必同时使用,下面这条表达式匹配所有以数字开头的行: 0-9 可以想见,“$”这样的写法将匹配空行。而“$”则是没有意义的,系统不会对这个表达式报错,但也不会输出任何东西。,21.1.7 字符转义,
7、读者可能已经有了这样的疑问:既然句点“.”在正则表达式中表示“除换行符之外的任意一个字符”,那么如何匹配句点“.”本身呢?这就需要用到转义字符“”。“”可以取消所有元字符的特殊含义,例如“.”匹配句点“.”,“”匹配左方括号“”而为了匹配“”,就要用“”来指定。例如下面这条正则表达式匹配“”: ,21.1.8 重复,用户有时候希望某个字符能够不只一次地出现。正则表达式中的星号“*”表示在它前面的模式应该重复0次或者多次。下面这条正则表达式用于匹配所有以“a”开头、以“t”结尾的行: a.*t$ 简单地讲解一下这条表达式:“a”匹配以“a”开头的行;“.”匹配一个字符(除了换行符);“*”指定之
8、前的那个字符(由“.”匹配)可以重复0次或多次;“t$”匹配以“t”结尾的行。 与此相类似的两个元字符是“+”和“?”。“+”指定重复1次或更多次;“?”指定重复0次或1次。下面这条正则表达式匹配所有在单词“hi”后面隔了一个或几个字符后出现单词“Jerry”的行: .+,21.1.9 子表达式,“子表达式”也被称为“分组”,这不是什么新的概念。小学生都知道,为了计算1+3的和与4的乘积,必须用括号把1+3括起来。正则表达式也一样,请看下面这个例子: $ egrep (or)2, /usr/share/dict/words sororities sorority sororitys,21.1.
9、10 反义,很多时候用户想说的是“除了这个字符,其他什么都可以”,这就需要用到“反义”。下面这条正则表达式匹配除了字母y的任何字符: y 与此相似的是,下面这条正则表达式匹配除了字母a、e、i、o、u的所有字符: aeiou 注意到“”在表示行首和反义时在位置上的区别。下面的例子匹配所有不以字母y开头的行: y,21.1.11 分支,读者已经看到,正则表达式对用户提交的信息简单地执行“与”的组合。举例来说,下面的这条语句匹配所有以字母h开头,“并且”以字母t结尾的行: ht$ 那么,如何匹配以字母h开头,“或者”以字母t结尾的行?分支(以竖线“|”表示)就用来完成“或”的组合。下面这条正则表达
10、式用于匹配以字母h开头,“或者”以字母t结尾的行: h|t$ 再看一个稍微复杂一些的例子。下面这一长串正则表达式可以匹配1到12月的英文写法,包括完整拼写和缩写形式: Jan(uary| |.)|Feb(uary| |.)|Mar(ch| |.)|Apr(il| |.)|May( |.)|Jun(e| |.)|Jul(y| |.)|Aug(ust| |.)|Sep(tember| |.)|Oct(ober| |.)|Nov(ember| |.)|Dec(ember| |.) 如果合在一起很难看清楚的话,下面以一月份为例分析这个正则表达式的写法: Jan(uary| |.),21.1.12 逆向
11、引用,在子表达式(分组)中捕获的内容可以在正则表达式中的其他地方再次使用,用户可以使用反斜杠()加上子表达式的编号来指代该分组匹配到的内容。这样的说法看上去有点不知所云,不妨来看几个例子: ().?( )*1,21.2 Shell脚本编程,这一节将正式开始介绍Shell脚本编程,严格地说是BASH Shell编程,这个“外壳”程序将贯穿于整本书。本节将尽可能多而清晰地向读者展现Shell编程的魅力,但也只是“尽可能多”而已。的确,要在这样一个小节内讲述Shell编程的全部细节是不现实的,很多介绍Shell编程的努力最终都变成了厚厚的一本书。读者如果希望了解更多这方面的内容,那么介绍UNIX S
12、hell编程的经典书籍都是值得推荐的资料。一再强调的是,这一节的内容只适合入门。,21.2.1 我需要什么工具?,写Shell脚本不需要编译器(和所有的脚本语言一样)、也不需要什么集成开发环境(也许有吧,但至少笔者还没有见到过)。所有的工具只是一个文本编辑器。Vim和Emacs无疑是Shell编程的首选工具,这是大部分主流程序员的选择。图形化的gedit和kate也是不错的选择,它们都支持对Shell脚本的语法加亮。 笔者的建议是,不必陷入编程工具优劣的争论。Vim、Emacs、gedit、kate抑或是其他文本编辑器都是不错的编写Shell脚本的工具,只要用的顺手就可以。如果找不到足够的理由
13、学习Vim和Emacs,那么就先放在一边吧。工具永远只是工具,使用工具做出些什么才是真正重要和值得去关心的。,21.2.2 第一个程序:Hello World!,这是最古老、最经典的入门程序,用于在屏幕上打印一行字符串“Hello World!”。借用这个程序,来看一看一个基本的Shell程序的构成。使用文本编辑器建立一个名为hello的文件,包含以下内容: #! /bin/bash #Display a line echo Hello World! 要执行这个Shell脚本,首先应该要为它加上可执行权限。完成这个操作后,就可以运行脚本了: $ chmod +x hello#为脚本加上可执行权
14、限,后文讲解时将省略这一步 $ ./hello Hello World!,21.2.3 变量和运算符,这一节介绍变量和运算符的使用。变量是任何一种编程语言所必备的元素,运算符也是。通过将一些信息保存在变量中,可以留作以后使用。通过这一节的学习,读者将学会如何操作变量和使用运算符。 1变量的赋值和使用 2变量替换 3位置变量 4BASH Shell引号规则 5运算符,21.2.4 表达式求值,之所以单独列出这一节,因为这是让很多初学者感到困惑的地方。Shell中进行表达式求值有和其他编程语言不同的地方。首先来看一个例子,这个例子可以“帮助”读者产生困惑。 $ num=1 $ num=$num+2
15、 $ echo $num 1+2,21.2.5 脚本执行命令和控制语句,本节将介绍Shell脚本中的执行命令以及控制语句。在正常情况下,Shell按顺序执行每一条语句,直至碰到文件尾。但在多数情况下,需要根据情况选择相应的语句执行,或者对一段程序循环执行。这些都是通过控制语句实现的。 1if选择结构 2case多选结构,21.2.6 条件测试,几乎所有初学Shell编程的人都会对这部分内容感到由衷的困惑。Shell和其他编程语言在条件测试上的表现非常不同,读者在C/C+积累的经验甚至可能会帮倒忙。理解这一节对顺利进行Shell编程至关重要,因此如果读者是第一次接触的话请耐心地读完这冗长的一节。
16、 1if判断的依据 2test命令和空格的使用,21.2.7 循环结构,循环结构用于反复执行一段语句,这也是程序设计中的基本结构之一。Shell中的循环结构有3种:while、until和for,下面逐一介绍这三种循环语句。 1while语句 2until语句 3for语句,21.2.8 读取用户输入,Shell程序并不经常和用户进行大量的交互,但一些时候接受用户的输入仍然是必须的。read命令提供了这样一个功能,从标准输入接受一行信息。在前面的几节中,读者已经在一些程序中使用了read命令,这里将进一步解释其中的细节。 read命令接受一个变量名作为参数,把从标准输入接收到的信息存放在这个变
17、量中。如果没有提供变量名,那么读取的信息将存放在变量REPLY中。下面的例子说明了这一点: $ read Hello World! $ echo $REPLY Hello World!,21.2.9 脚本执行命令,下面介绍另两条用于控制脚本行为的命令:exit和trap,前者退出脚本并返回一个特定的值,后者用于捕获信号。合理地使用这两条命令,可以使脚本的表现更为灵活高效。 1exit命令 2trap命令,21.2.10 创建命令表,21.2.6节(条件测试)中已经提到,test命令的-a和-o参数执行第二条测试命令的情况是不同的,这一点同样适用于Shell内建的“&”和“|”。事实上,“&”和
18、“|”更多地被用来创建命令表,命令表可以利用一个命令的退出值来控制是否执行另一条命令。下面这条命令取自系统的rc脚本: -d /etc/rc.boot & run-parts /etc/rc.boot,21.2.11 其他有用的Shell编程工具,这一节介绍一些有用的Shell工具。这些工具在之前的章节中没有出现,但是可能对从事Shell编程的用户会很有用。其中一些和脚本编程密切相关,另一些则是关于文件操作的。 1cut命令 2diff命令 3sort命令 4uniq命令 5tr命令 6wc命令 7substr命令 8seq命令,21.2.12 定制工具:安全的delete命令,系统的rm命令
19、常常导致一些不愉快的事情。默认情况下rm不会在删除文件前提示用户是否真的想这么做,删除后也不能再从系统中恢复。这意味着用户不得不为自己的一时糊涂付出惨痛的代价。Shell编程总是能帮助用户摆脱类似的烦恼:系统没有的,就自己动手创造。这一节将设计一个相对“安全”的delete命令来替代rm。好吧,废话少说,首先来看一下究竟有哪些事情需要去做: 在用户的主目录中添加目录.trash用作“回收站”; 在每次删除文件和目录前向用户确认; 将需要“删除”的文件和目录移动到/.trash中。,21.3 Shell定制,本节介绍如何在Shell中设置环境变量,以及如何使用别名。到目前为止,读者已经掌握了足够
20、多的和Shell有关的知识,这部分的内容将帮助读者定制自己的Shell。创建一个足够顺手的工作环境总会让人心情愉快。,21.3.1 修改环境变量,“环境变量”是一些和当前Shell有关的变量,用于定义特定的Shell行为。餐厅的服务员必须依照菜单给顾客上菜,Shell也一样。使用printenv命令可以查看当前Shell环境中所有的环境变量: $ printenv#显示环境变量 GPG_AGENT_INFO=/tmp/seahorse-O0kojq/S.gpg-agent:7473:1 SHELL=/bin/bash TERM=xterm DESKTOP_STARTUP_ID= XDG_SES
21、SION_COOKIE=655ca7009509be1906041979490c7421-1231999675.14837-1239878042 GTK_RC_FILES=/etc/gtk/gtkrc:/home/lewis/.gtkrc-1.2-gnome2 WINDOWID=79691867 USER=lewis http_proxy=01:6666/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games DISPLAY=:0.0 GTK_IM_MODUL
22、E=scim-bridge LESSCLOSE=/usr/bin/lesspipe %s %s COLORTERM=gnome-terminal,21.3.2 设置别名,别名是BASH Shell的一个特性,使用别名可以简化命令的输入。如果正在使用openSUSE,可以试试下面这个命令: $ l#字母“l” drwxr-xr-x 2 lewis lewis 4096 2008-11-08 08:57 account drwx- 2 root root 4096 2008-11-04 21:39 Desktop lrwxrwxrwx 1 lewis lewis 26 2008-11-01 23:19 Examples - /usr/share/example-content -rw-r-r- 1 lewis lewis 27504640 2008-11-07 15:50 linux_book_bak.tar drwxr-xr-x 2 lewis lewis 4096 2008-11-08 16:02 shell -rw-r-r- 1 lewis lewis 1306 2008-11-02 00:0
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 重度脱水护理问题
- 下肢骨科护理
- 京剧初级考试题目及答案
- 基于人工智能的2025年建筑施工安全管理信息化应用探索报告
- 汽车轻量化材料在汽车零部件产业智能交通知识产权中的应用报告
- 绿色金融产品创新与2025年绿色金融市场创新驱动因素分析研究报告
- 2025年员工安全培训考试试题附答案【轻巧夺冠】
- 卧床老人康复护理
- 黑龙江省五常市部分校2026届中考联考英语试卷含答案
- 2026届河南省商丘市虞城县求实学校中考四模数学试题含解析
- 法律律师委托协议书模板
- 电力设备安装人员安全教育培训手册
- 2024-2025学年重庆市沙坪坝区南开中学七年级(下)期末数学试卷
- 转店定金合同协议书模板
- 机械能及其转化(作业)原卷版-2023学年八年级物理下册(人教版)
- 教育金保险理念
- 无废工厂培训
- 物业服务合同培训课件
- 腰痛的预防和治疗讲解讲课件
- 2025年浙江省中考数学试卷(含答案)
- 双拥教育课件
评论
0/150
提交评论