LINUX与UNIX SHELL编程指南018.pdf
《LINUX与UNIX SHELL编程指南018.pdf》由会员分享,可在线阅读,更多相关《LINUX与UNIX SHELL编程指南018.pdf(42页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、下载第18章 控制流结构所有功能脚本必须有能力进行判断,也必须有能力基于一定条件处理相关命令。本章讲述这方面的功能,在脚本中创建和应用控制结构。本章内容有:退出状态。while、f o r和until loops循环。if then else语句。脚本中动作。菜单。18.1 退出状态在书写正确脚本前,大概讲一下退出状态。任何命令进行时都将返回一个退出状态。如果要观察其退出状态,使用最后状态命令:$echo$?主要有4种退出状态。前面已经讲到了两种,即最后命令退出状态$?和控制次序命令($、|)。其余两种是处理s h e l l脚本或s h e l l退出及相应退出状态或函数返回码。在第 1 9
2、章讲到函数时,也将提到其返回码。要退出当前进程,s h e l l提供命令e x i t,一般格式为:exit n其中,n为一数字。如果只在命令提示符下键入e x i t,假定没有在当前状态创建另一个s h e l l,将退出当前s h e l l。如果在脚本中键入e x i t,s h e l l将试图(通常是这样)返回上一个命令返回值。有许多退出脚本值,但其中相对于脚本和一般系统命令最重要的有两种,即:退出状态0 退出成功,无错误。退出状态1 退出失败,某处有错误。可以在s h e l l脚本中加入自己的退出状态(它将退出脚本)。本书鼓励这样做,因为另一个s h e l l脚本或返回函数可
3、能要从 s h e l l脚本中抽取退出脚本。另外,相信加入脚本本身的退出脚本值是一种好的编程习惯。如果愿意,用户可以在一个用户输入错误后或一个不可覆盖错误后或正常地处理结束后退出脚本。注意 从现在起,本书所有脚本都将加入注释行。注释行将解释脚本具体含义,帮助用户理解脚本。可以在任何地方加入注释行,因为其本身被解释器忽略。注释行应以#开头。18.2 控制结构几乎所有的脚本里都有某种流控制结构,很少有例外。流控制是什么?假定有一个脚本包含下列几个命令:上述脚本问题出在哪里?如果目录创建失败或目录创建成功文件拷贝失败,如何处理?这里需要从不同的目录中拷贝不同的文件。必须在命令执行前或最后的命令退出
4、前决定处理方法。s h e l l会提供一系列命令声明语句等补救措施来帮助你在命令成功或失败时,或需要处理一个命令清单时采取正确的动作。这些命令语句大概分两类:循环和流控制。18.2.1 流控制i f、t h e n、e l s e语句提供条件测试。测试可以基于各种条件。例如文件的权限、长度、数值或字符串的比较。这些测试返回值或者为真(0),或者为假(1)。基于此结果,可以进行相关操作。在讲到条件测试时已经涉及了一些测试语法。c a s e语句允许匹配模式、单词或值。一旦模式或值匹配,就可以基于这个匹配条件作其他声明。18.2.2 循环循环或跳转是一系列命令的重复执行过程,本书提到了 3种循环
5、语句:for 循环每次处理依次列表内信息,直至循环耗尽。Until 循环此循环语句不常使用,u n t i l循环直至条件为真。条件部分在循环末尾部分。While 循环w h i l e循环当条件为真时,循环执行,条件部分在循环头。流控制语句的任何循环均可嵌套使用,例如可以在一个 f o r循环中嵌入另一个f o r循环。现在开始讲解循环和控制流,并举一些脚本实例。从现在起,脚本中 e c h o语句使用L I N U X或B S D版本,也就是说使用 e c h o方法echo-e-n,意即从e c h o结尾中下一行执行命令。应用于 U N I X(系统V和B S D)的统一的e c h
6、o命令参阅1 9章s h e l l函数。18.3 if then else语句i f语句测试条件,测试条件返回真(0)或假(1)后,可相应执行一系列语句。i f语句结构对错误检查非常有用。其格式为:if 条件1then 命令1elif 条件2then 命令2else 命令3第18章 控制流结构161下载f i让我们来具体讲解i f语句的各部分功能。If 条件1 如果条件1为真Then 那么命令1 执行命令1elif 条件2 如果条件1不成立then 那么命令2 执行命令2else 如果条件1,2均不成立命令3 那么执行命令3fi 完成i f语句必须以单词f i终止。在i f语句中漏写f i是
7、最一般的错误。我自己有时也是这样。e l i f和e l s e为可选项,如果语句中没有否则部分,那么就不需要 e l i f和e l s e部分。I f语句可以有许多e l i f部分。最常用的i f语句是if then fi结构。下面看一些例子。18.3.1 简单的if语句最普通的i f语句是:i f条件then 命令f i使用i f语句时,必须将t h e n部分放在新行,否则会产生错误。如果要不分行,必须使用命令分隔符。本书其余部分将采取这种形式。现在简单 i f语句变为:if 条件;t h e n命令f i注意,语句可以不这样缩排,但建议这样做,因为可以增强脚本的清晰程度。在条件流下
8、采取命令操作更方便。下面的例子测试 1 0是否小于1 2,此条件当然为真。因为条件为真,i f语句内部继续执行,这里只有一个简单的 e c h o命令。如果条件为假,脚本退出,因为此语句无e l s e部分。18.3.2 变量值测试通过测试设置为接受用户输入的变量可以测知用户是否输入信息。下面的例子中测试用162第四部分 基础s h e l l编程下载户键入r e t u r n键后变量n a m e是否包含任何信息。18.3.3 grep输出检查不必拘泥于变量或数值测试,也可以测知系统命令是否成功返回。对 g r e p使用i f语句找出g r e p是否成功返回信息。下面的例子中 g r
9、e p用于查看D a v e是否在数据文件 d a t a.f i l e中,注意D a v e 用于精确匹配。上面的例子中,g r e p输出定向到系统垃圾堆。如果匹配成功,g r e p返回0,将g r e p嵌入i f语句;如果g r e p成功返回,i f部分为真。18.3.4 用变量测试grep输出正像前面看到的,可以用 g r e p作字符串操作。下面的脚本中,用户输入一个名字列表,g r e p在变量中查找,要求其包含人名P e t e r。以下是对应输入名称的输出信息。第18章 控制流结构163下载18.3.5 文件拷贝输出检查下面测试文件拷贝是否正常,如果 c p命令并没有拷
10、贝文件 m y f i l e到m y f i l e.b a k,则打印错误信息。注意错误信息中 basename$0打印脚本名。如果脚本错误退出,一个好习惯是显示脚本名并将之定向到标准错误中。用户应该知道产生错误的脚本名。注意,文件可能没找到,系统也产生本身的错误信息,这类错误信息可能与输出混在一起。既然已经显示系统错误信息获知脚本失败,就没必要显示两次。要去除系统产生的错误和系统输出,只需简单的将标准错误和输出重定向即可。修改脚本为:/dev/null 2&1。脚本运行时,所有输出包括错误重定向至系统垃圾堆。18.3.6 当前目录测试当运行一些管理脚本时,可能要在根目录下运行它,特别是移
11、动某种全局文件或进行权限改变时。一个简单的测试可以获知是否运行在根目录下。下面脚本中变量 D I R E C TO RY使用当前目录的命令替换操作,然后此变量值与 /字符串比较(/为根目录)。如果变量值与字符串不等,则用户退出脚本,退出状态为 1意味错误信息产生。164第四部分 基础s h e l l编程下载18.3.7 文件权限测试可以用i f语句测试文件权限,下面简单测试文件 t e s t.t x t是否被设置到变量L O G N A M E。18.3.8 测试传递到脚本中的参数i f语句可用来测试传入脚本中参数的个数。使用特定变量$#,表示调用参数的个数。可以测试所需参数个数与调用参数
12、个数是否相等。以下测试确保脚本有三个参数。如果没有,则返回一个可用信息到标准错误,然后代码退出并显示退出状态。如果参数数目等于 3,则显示所有参数。如果只传入两个参数,则显示一可用信息,然后脚本退出。这次传入三个参数。18.3.9 决定脚本是否为交互模式有时需要知道脚本运行是交互模式(终端模式)还是非交互模式(c r o n或a t)。脚本也许第18章 控制流结构165下载需要这个信息以决定从哪里取得输入以及输出到哪里,使用 t e s t命令并带有-t选项很容易确认这一点。如果t e s t返回值为1,则为交互模式。18.3.10 简单的if else语句下一个i f语句有可能是使用最广泛的
13、:if 条件t h e n命令1e l s e命令2f i使用i f语句的e l s e部分可在条件测试为假时采取适当动作。18.3.11 变量设置测试下面的例子测试环境变量 E D I TO R是否已设置。如果E D I TO R变量为空,将此信息通知用户。如果已设置,在屏幕上显示编辑类型。18.3.12 检测运行脚本的用户下面例子中,环境变量用于测试条件,即 L O G N A M E是否包含r o o t值。这类语句是加在脚本开头作为一安全性准则的普遍方法。当然 L O G N A M E可用于测试任何有效用户。如果变量不等r o o t,返回信息到标准错误输出即屏幕,也就是通知用户不是
14、 r o o t,脚本然后退出,并带有错误值1。如果字符串r o o t等于L O G N A M E变量,e l s e部分后面语句开始执行。实际上,脚本会继续进行正常的任务处理,这些语句在 f i后面,因为所有非 r o o t用户在脚本的前面测试部分已经被剔出掉了。166第四部分 基础s h e l l编程下载18.3.13 将脚本参数传入系统命令可以向脚本传递位置参数,然后测试变量。这里,如果用户在脚本名字后键入目录名,脚本将重设$1特殊变量为一更有意义的名字。即 D I R E C TO RY。这里需测试目录是否为空,如果目录为空,ls-A将返回空,然后对此返回一信息。也可以使用下面
15、的脚本替代上面的例子并产生同样的结果。18.3.14 null:命令用法到目前为止,条件测试已经讲完了 t h e n和e l s e部分,有时也许使用者并不关心条件为真或为假。不幸的是i f语句各部分不能为空一些语句已经可以这样做。为解决此问题,s h e l l提供了:空命令。空命令永远为真(也正是预想的那样)。回到前面的例子,如果目录为空,可以只在t h e n部分加入命令。第18章 控制流结构167下载18.3.15 测试目录创建结果现在继续讨论目录,下面的脚本接受一个参数,并用之创建目录,然后参数被传入命令行,重设给变量D I R E C TO RY,最后测试变量是否为空。if$DI
16、RECTORY=也可以用if$#-lt 1来进行更普遍的参数测试。如果字符串为空,返回一可用信息,脚本退出。如果目录已经存在,脚本从头至尾走一遍,什么也没做。创建前加入提示信息,如果键入Y或y,则创建目录,否则使用空命令表示不采取任何动作。使用最后命令状态测试创建是否成功执行,如果失败,返回相应信息。168第四部分 基础s h e l l编程下载执行上述脚本,显示:18.3.16 另一个拷贝实例在另一个拷贝实例中,脚本传入两个参数(应该包含文件名),系统命令c p将$1拷入$2,输出至/d e v/n u l l。如果命令成功,则仍使用空命令并且不采取任何动作。另一方面,如果失败,在脚本退出前
17、要获知此信息。脚本运行,没有拷贝错误:脚本运行带有拷贝错误:下面的脚本用s o r t命令将文件a c c o u n t s.q t r分类,并输出至系统垃圾堆。没人愿意观察屏幕上3 0 0行的分类页。成功之后不采取任何动作。如果失败,通知用户。18.3.17 多个if语句可能有时要嵌入i f语句。为此需注意i f和f i的相应匹配使用。18.3.18 测试和设置环境变量前面已经举例说明了如何测试环境变量 E D I TO R是否被设置。现在如果未设置,则进一步为其赋值,脚本如下:第18章 控制流结构169下载脚本工作方式如下:首先检查是否设置了该变量,如果已经赋值,输出信息提示使用 v i
18、作为缺省编辑器。v i被设置为编辑器,然后脚本退出。如果未赋值,则提示用户,询问其是否要设置该值。检验用户输入是否为大写或小写y,输入为其他值时,脚本退出。如果输入Y或y,再提示输入编辑类型。使用$E D I TO R=“”测试用户是否未赋值和未点击r e t u r n键。一种更有效的方法是使用-z$EDITO R方法,本文应用了这两种方法。如果测试失败,返回信息到屏幕,即使用v i做缺省编辑器,因而E D I TO R赋值为v i。如果用户输入了一个名字到变量 E D I TO R,则使用它作为编辑器并马上让其起作用,即导出变量E D I TO R。18.3.19 检测最后命令状态前面将目
19、录名传入脚本创建了一个目录,脚本然后提示用户是否应创建目录。下面的例子创建一个目录,并从当前目录将所有*.t x t文件拷入新目录。但是这段脚本中用最后状态命令检测了每一个脚本是否成功执行。如果命令失败则通知用户。170第四部分 基础s h e l l编程下载18.3.20 增加和检测整数值下面的例子进行数值测试。脚本包含了一个计数集,用户将其赋予一个新值就可改变它。脚本然后将当前值1 0 0加入一个新值。工作流程如下:用户输入一个新值改变其值,如果键入回车键,则不改变它,打印当前值,脚本退出。如果用户用y或Y响应新值,将提示用户输入增量。如果键入回车键,原值仍未变。键入一个增量,首先测试是否
20、为数字,如果是,加入计数 C O U N TO R中,最后显示新值。第18章 控制流结构171下载运行结果如下:18.3.21 简单的安全登录脚本以下是用户登录时启动应用前加入相应安全限制功能的基本框架。首先提示输入用户名和密码,如果用户名和密码均匹配脚本中相应字符串,用户登录成功,否则用户退出。脚本首先设置变量为假总是假定用户输入错误,s t t y当前设置被保存,以便隐藏p a s s w d域中字符,然后重新保存s t t y设置。如果用户I D和密码正确(密码是m a y d a y),明亮I N VA L I D _ U S E R和I N VA L I D _ PA S S W D
21、设置为n o表示有效用户或密码,然后执行测试,如果两个变量其中之一为 y e s,缺省情况下,脚本退出用户。键入有效的I D和密码,用户将允许进入。这是一种登录脚本的基本框架。下面的例子中有效用户I D为d a v e或p a u l i n e。172第四部分 基础s h e l l编程下载如果运行上述脚本并给一个无效用户:现在给出正确的用户和密码:18.3.22 elif用法if then else语句的e l i f部分用于测试两个以上的条件。18.3.23 使用elif进行多条件检测使用一个简单的例子,测试输入脚本的用户名。脚本首先测试是否输入一个名字,如果没有,则什么也不做。如果输入
22、了,则用 e l i f测试是否匹配r o o t、l o u i s e或d a v e,如果不匹配其中任何一个,则打印该名字,通知用户不是 r o o t、l o u i s e或d a v e。第18章 控制流结构173下载运行上述脚本,给出不同信息,得结果如下:18.3.24 多文件位置检测假定要定位一个用户登录文件,已知此文件在/u s r/o p t s/a u d i t/l o g s或/u s r/l o c a l/a u d i t/l o g s中,具体由其安装人决定。在定位此文件前,首先确保文件可读,此即脚本测试部分。如果未找到文件或文件不可读,则返回错误信息。脚本如
23、下:174第四部分 基础s h e l l编程下载运行上面脚本,如果文件在上述两个目录之一中并且可读,将可以找到它。如果不是,返回错误并退出,下面结果失败,因为假想的文件并不存在。18.4 case语句c a s e语句为多选择语句。可以用 c a s e语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。c a s e语句格式如下:case 值 i n模式1 命令1.;模式2)命令2.;e s a cc a s e工作方式如上所示。取值后面必须为单词 i n,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至;。取值将检测匹配的每一个模
24、式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号*捕获该值,再接受其他输入。模式部分可能包括元字符,与在命令行文件扩展名例子中使用过的匹配模式类型相同,即:*任意字符。?任意单字符。.类或范围中任意字符。下面举例说明。18.4.1 简单的case语句下面的脚本提示输入 1到5,输入数字传入 c a s e语句,变量A N S设置为c a s e取值测试变量A N S,A N S将与每一模式进行比较。如果匹配成功,则执行模式里面的命令直至;;,这里只反馈非用户数字选择的信息,然后c a s e退出,因为匹配已找到。进程在c a s e语句后仍可继续执行。如
25、果匹配未找到,则使用*模式捕获此情况,这里执行错误信息输出。第18章 控制流结构175下载给出不同输入,运行此脚本。使用模式*捕获范围之外的取值情况。18.4.2 对匹配模式使用|使用c a s e时,也可以指定“|”符号作为或命令,例如v t 1 0 0|v t 1 0 2匹配模式v t 1 0 0或v t 1 0 2。下面的例子中,要求用户输入终端类型。如果输入为v t 1 0 0或v t 1 0 2,将匹配模式v t 1 0 0|v t 1 0 2,执行命令是设置 T E R M变量为v t 1 0 0。如果用户输入与模式不匹配,*用来捕获输入,其中命令为将T E R M设置为v t 1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LINUX与UNIX SHELL编程指南018 LINUX UNIX SHELL 编程 指南 018
限制150内