第9章Shell程序设计第9章Shell程序设计9.1Shell语言概述9.2Shell特殊字符9.3Shell变量9.4Shell表达式9.5Shell控制结构9.6Shell程序综合举例习题第9章Shell程序设计9.1Shell语言概述9.1.1Shell语言的特点与其他编程语言相比,Shell语言具有如下特点:(1) Shell是一种解释性语言。这就是说,用Shell语言写的程序不需编译,可以直接由Shell进程解释执行。解释性语言的特点是快捷方便,可以即编即用,但与编译性语言的目标程序来比,解释性语言程序的运行速度要低一些。(2) Shell是基于字符串的语言。Shell只是做字符串处理,不支持复杂的数据结构和运算。Shell的输出也全部是字符方式的。第9章Shell程序设计(3) Shell是命令级语言。Shell程序全部由命令而不是语句组成,几乎所有的Shell命令和可执行程序都可用来编写Shell程序。Shell命令十分丰富,命令的组合功能也十分强大。所以,用简单的命令和命令组合形成的Shell程序即简洁又高效,可以实现各种复杂的功能。另外需要说明的是,不同版本的Shell程序不完全兼容,差别可能是细微的,也可能是明显的。本章介绍的是Bash编程,它的应用较广泛,兼容性也很好。第9章Shell程序设计9.1.2Shell程序Shell程序也称Shell脚本(script),是由一系列Shell命令为基本元素构成的文本文件。简单的Shell程序可以只是一个命令序列,高级Shell程序中还可以包含复杂的命令组合,定义各种参数和变量、使用条件命令、控制结构以及其他高级特性。例9.1第1个Shell程序:$cathello#hello程序#Thisisashellscripttosayhello.echoHelloWorld!第9章Shell程序设计echo-n“Todayis”date“+%A,%B%d,%Y.”$.hello#运行hello程序HelloWorld!TodayisSaturday,October13,2007.$这个hello程序的第1行是注释,后面3行是命令。在执行此程序时,Shell依次执行这3个命令并输出显示信息。第9章Shell程序设计Shell程序中的成分:Shell脚本是以行为单位的,在执行脚本的时候会分解成一行一行依次执行。脚本中所包含的成分主要有:注释、命令、Shell变量和结构控制语句。注释:用于对脚本进行解释和说明,在注释行的前面加上符号#,这样在执行脚本的时候Shell就不会对该行进行解释。命令:在Shell脚本中可以出现任何在交互方式下可以使用的命令。变量:Shell支持字符串变量和整型变量结构控制语句:用于编写复杂脚本的流程控制语句第9章Shell程序设计9.1.3Shell程序的建立与执行Shell脚本是文本文件,因此可以用任何文本编辑器(如vi、emacs等)建立和编辑脚本。Shell脚本文件的名称没有限定的扩展名,通常不带扩展名或带“.sh”扩展名。Shell脚本的执行方式主要有3种。(1)将脚本作为可执行文件执行:$chmoda+xhello$./hello用文本编辑器生成的脚本文件默认是没有x权限的,也就是说是不可直接执行的。赋予x权限后,脚本就可以像一般的Shell命令那样执行了。如果脚本不在系统存放命令的标准目录下,需要在执行时指定脚本的路径。上例中脚本hello放在当前目录下,所以要用./hello来运行。第9章Shell程序设计(2)启动一个Shell子进程来执行脚本文件:$bashhello#或bashhello执行此命令行时,Shell进程先启动一个bash子进程,让它执行hello脚本的内容,执行完毕后bash子进程也终止。在这种方式中,脚本是作为命令参数传给子Shell的。子Shell运行时读取该文件并执行其内容,因此脚本文件不必有执行权限。这种方法常用于运行一个其他版本的Shell脚本。假如当前Shell是bash,而chello是用CShell语言写的脚本,则要执行这个脚本时可以用cshchello命令启动一个csh进程来执行它。第9章Shell程序设计(3)让当前Shell进程执行脚本文件:$.hello#注意.后面的空格“.”是一个Shell内部命令,hello是它的参数。“.”命令的功能是读取参数指定的文件,执行其内容。这种执行方式与第2种方式类似,区别在于此方式是由当前Shell进程来执行脚本文件的。第9章Shell程序设计9.2Shell特殊字符Shell定义了一些特殊的字符,称为元字符(meta-characters),它们对Shell有特殊的含义。Shell在读入命令行后,要先对命令行进行扫描,找出元字符并进行相应的替换或处理,以确定要执行的程序和它的参数及执行方式等。Shell的元字符包括:文件通配符、输入/输出重定向及管道符、注释符、命令执行控制符、命令组合与替换符、转义符等。恰当地运用这些字符能够使Shell的功能得到充分发挥。以下分类介绍这些特殊字符的含义和用法。第9章Shell程序设计9.2.1通配符通配符用于描述命令中的文件名参数。当Shell在命令的参数中遇到带有通配符的文件名模式时,它将目录中的所有文件与该模式进行匹配,并用匹配的文件名替换参数中的文件名模式。表9-1列出了常用的通配符。第9章Shell程序设计表9-1常用的文件名通配符符号格式含义*匹配任何字符串,包括空字符串?匹配任何单个字符[]匹配方括号内列出的某个单个字符,[字符1,字符2,…]指定多个匹配的字符-[开始字符-结束字符]指定匹配的字符范围![!字符]指定不匹配的字符第9章Shell程序设计利用通配符来描述文件参数可以简化对多个文件的处理操作。例9.2示意了用通配符构造的文件名模式与文件名之间的匹配关系。例9.2通配符的匹配作用:zip*匹配以字符zip开始的任何字符串;*zip匹配以字符zip结尾的任何字符串;rc?.d匹配以rc开始、以.d结束,中间为任何单个字符的字符串;[a-d,x,y]匹配字符a、b、c、d、x、y;[!Z]匹配不为Z的单个字符;[a-f]*匹配字符a到f开头的字符串,如abc,d2,e3.c,f.dat;*[!o]匹配不以o结尾的字符串。第9章Shell程序设计9.2.2输入/输出重定向与管道符输入/输出重定向和管道符的作用是改变命令的输入/输出环境。当Shell在命令行中遇到输入/输出重定向或管道符时,它将对命令的标准输入/输出文件作相应的更改,然后再执行命令。表9-2列出了常用的输入/输出重定向与管道符。第9章Shell程序设计表9-1常用的输入/输出重定向与管道符符号格式含义命令文件标准输入重定向命令文件标准输出重定向2命令2文件标准错误输出重定向&命令&文件标准输出合并重定向2&1命令2&1文件将标准错误输出归并到标准输出流中1&2命令1&2文件将标准输出归并到标准错误输出流中命令文件标准输出附加重定向2命令2文件标准错误输出附加重定向命令字符串here文档重定向|命令|命令管道|tee命令|tee文件|命令T型管道第9章Shell程序设计1.标准输入/输出重定向“”是标准输入重定向符,它将标准输入stdin重定向到一个文件。“”是标准输出重定向符,它将标准输出重定向到一个文件。为了区分是哪种输出重定向,可以在符号前加一个文件描述符fd。stdout的fd是1,stderr的fd是2,所以1表示标准输出重定向,2表示标准错误输出重定向。未指定fd时,默认地表示是1。例9.3将标准输入改为infile,标准输出改为outfile,标准错误输出改为errfile文件:$myprocoutfile2errfileinfile第9章Shell程序设计2.合并重定向与归并重定向“&”是标准输出合并重定向符,它将标准输出与标准错误输出合在一起重定向到一个文件。“&”是标准输出归并重定向符,它将一种标准输出归并到另一种标准输出流中。符号的前后各用一个fd来表示归并的方式。1&2表示将stdout归并到stderr流中,&2默认地表示是1&2。2&1表示将stderr归并到stdout流中。例9.4将标准输出和标准错误输出改向到out文件:$myprog&out第9章Shell程序设计例9.5将标准输出改向到out文件,并将标准错误输出并入到标准输出中:$myprogout2&1#等价于myprog&out例9.6将标准输出并入标准错误输出流:$myprog1&2#避免标准输出被管道改向第9章Shell程序设计3.附加重定向“”是标准输出附加重定向符,它将标准输出stdout或标准错误输出stderr用追加的方式重定向到一个文件。1或表示stdout附加重定向,2表示stderr附加重定向。例9.7在.bash_profile文件的尾部添加一行:$echo‘PATH=$PATH:.’.bash_profile4. here文档“”是一种特殊的标准输入重定向机制,称为“here文档(heredocument)”。here文档的表示格式是“结束标记字符串”,它的作用是指示Shell将本命令行后面的输入行作为命令的标准输入传给命令,直到遇到结束标记字符串为止。第9章Shell程序设计例9.8here文档的使用:$sortEndJoneDoeDavidNiceMasoodShahEndDavidNiceJoneDoeMasoodShah$cathere-doctestsortEnd第9章Shell程序设计JoneDoeDavidNiceMasoodShahEnd$here-doctestDavidNiceJoneDoeMasoodShah$here文档主要用在Shell脚本中。它允许将脚本中某个命令的标准输入直接写在该命令行之后。这样,当执行到该命令行时,它不再去等待标准输入而是在本文档内(here文档)直接获取输入进行处理,如上例中here-doctest脚本所示。第9章Shell程序设计5.管道“|”是管道符,它将前一命令的标准输出作为后一命令的标准输入。“|tee”是T型管道符,它将前一命令的标准输出存入一个文件中,并传递给后一命令作为标准输入。例9.9将一个目录下的文件列表按名逆序排序后浏览:$ls/dev|sort-r|more例9.10将一个文件的内容排序后保存并统计其行数:$sortmylist|teesort-list|wc-l第9章Shell程序设计9.2.3命令执行控制符命令执行控制符用于控制命令的执行方式,指示Shell何时该执行这个命令以及在何处(前台、后台)执行这个命令。表9-3列出了常用的命令执行控制符。第9章Shell程序设计表9-1常用的命令执行控制符符号格式含义;命令1;命令2顺序执行命令1和命令2&&命令1&&命令2“逻辑与”执行,若命令1执行成功则执行命令2;否则不执行命令2||命令1||命令2“逻辑或”执行。若命令1执行成功则不执行命令2;否则继续执行命令2&命令&后台执行命令第9章Shell程序设计1.顺序执行“;”是顺序执行符,它将两个或多个命令组合在一个命令行中,指示Shell顺序执行这些命令。例9.11转到上一级目录,显示目录的路径名和目录的文件列表:$cd..;pwd;ls第9章Shell程序设计2.条件执行“&&”是逻辑与执行符,它将两个或多个命令组合在一个命令行中,指示Shell依次执行这些命令直到某个命令失败为止。“||”是逻辑或执行符,它将两个或多个命令组合在一个命令行中,指示Shell依次执行这些命令直到某个命令成功为止。例9.12将文件file1复制到file2,如果成功则删除file1:$cpfile1file2&&rmfile1例9.13将文件file1复制到file2,如果失败则显示file1:$cpfile1file