10-2shell编程.ppt
Linux Shell编程编程shell程序设计的流程控制和其他高级程序设计语言一样,shell提供了用来控制程序执行流程的命令,包括条件分支和循环结构,用户可以用这些命令建立非常复杂的程序。与传统的语言不同的是,shell用于指定条件值的不是布尔表达式而是命令和字符串。test测试命令test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试,其测试符和相应的功能分别如下:(1)数值测试:-eq:等于则为真-ne:不等于则为真-gt:大于则为真-ge:大于等于则为真-lt:小于则为真-le:小于等于则为真(2)字符串测试:=:等于则为真!=:不相等则为真-z字符串:字符串长度伪则为真-n字符串:字符串长度不伪则为真(3)文件测试:-e文件名:如果文件存在则为真-r文件名:如果文件存在且可读则为真-w文件名:如果文件存在且可写则为真-x文件名:如果文件存在且可执行则为真-s文件名:如果文件存在且至少有一个字符则为真-d文件名:如果文件存在且为目录则为真-f文件名:如果文件存在且为普通文件则为真-c文件名:如果文件存在且为字符型特殊文件则为真-b文件名:如果文件存在且为块特殊文件则为真另外,Linux还提供了与(“!”)、或(“-o)、非(“-a”)三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。example$test3-gt4&echotrue|echofalse示例中,-gt操作符对两个字符值之间执行算术比较$abc!=def;echo$?用的形式比较两个字符串不相等$test-d$HOME;echo$?测试HOME变量的值,用单目操作符-d检查它是不是目录testabc=def;echo$?$abc!=def;echo$?$abcdef;echo$?$abcabc;echo$?if条件语句shell程序中的条件分支是通过if条件语句来实现的,其一般格式为:if条件命令串then条件为真时的命令串else条件为假时的命令串fiififthenelifthenelsefielif和else是可选项例子#!/bin/bashnum1=10num2=11if$num1-gt5thenechothetestvalue$num1isgreaterthan5fiif$num2-eq$num1thenechothevaluesareequalelseechothevaluesaredifferentfi#!/bin/bashtestuser=rootif$USER!=$testuserthenechothisisnot$testuserelseechowelcome$testuserfi#!/bin/bashstr1=aaastr2=bbbif$str1$str2thenecho$str1isgreaterthan$str2elseecho$str1islessthan$str2fi在脚本中单独使用了大于号,虽然没报错,但结果是错误的#!/bin/bashstr1=aaastr2=bbbif$str1$str2thenecho$str1isgreaterthan$str2elseecho$str1islessthan$str2fi#!/bin/bashstr1=aaastr2=if-n$str1/长度是否大于0thenechothestring$str1isnotemptyelseechothestring$str1isemptyfiif-z$str2/长度是否为0thenechothestring$str2isemptyelseechothestring$str2isnotemptyfiif-z$str3/长度是否为0thenechothestring$str3isemptyelseechothestring$str3isnotemptyfi使用-f确定对象是文件#!/bin/bashif-e$HOMEthenechothe$HOMEexists!if-f$HOMEthenechoyes,itisafileelseechono,itisnotafileif-f$HOME/.bash_historythenechobut$HOME/.bash_historyisafileelseechoitisnotafiletoofifielseechothereisnotobject!fi-d确定是否目录#!/bin/bashif-d$HOMEthenechoyourhomedirectoryexistscd$HOMElselseechothereissometingwrongfi-e检测对象是否存在#!/bin/bashif-e$HOMEthenechotheHDexistsif-e$HOME/myfilethenechothemyfileexistselsetouch$HOME/myfileechocreatingnewfilenamemyfilefifi通过-r可检测可读性#!/bin/bashtestfile=/etc/shadowif-f$testfilethenif-r$testfilethenls-l$testfileelseechoimunabletoreadthefilefielseechothefiledoesntexistfi通过-s检测文件是否为空#!/bin/bashfile=testfiletouch$fileif-s$filethenechothefileexistsandhasdatainitelseechothefileexistsbutemptyfidate$fileif-s$filethenechothefileexistsandhasdatainitelseechothefileexistsbutemptyfi通过-w检测文件是否可写#!/bin/bashfile=$HOME/testfiletouch$filechmodu-w$filenow=dateif-w$filethenechothefilecouldbewrittenelseechothefilecouldntbewrittenfichmodu+w$fileif-w$filethenechothefilecouldbewritten$now$HOME/testfileechoandthefileviews$fileelseechothefilecouldntbewrittenfi通过-x可以检测文件是否可被执行#!/bin/bashfile=$HOME/testfile2touch$filechmodu+x$fileif-x$filethenechothefilecouldberunelseechothefilecouldntberunfi通过-O可以检测文件的所有者#!/bin/bashfile=/etc/passwdif-O$filethenechoyouaretheownerofthe$fileelseechoyouarenttheownerofthe$filefi-G检测文件的默认组#!/bin/bashfile=/etc/passwdif-G$filethenechoyouareinthesamegroupas$fileelseechoyouarentinthesamegroupasthe$filefi通过-nt和-ot来比较两个文件之间的新旧,这里指的是创建或修改日期#!/bin/bashif$HOME/aa-nt$HOME/bbthenechotheaaisnewerthanbbelseechotheaaisolderthanbbfi复合条件检测#!/bin/bashif-d$HOME&-w$HOMEthenechothefileexistsandyoucanwirte$HOMEelseechoyoucantwritethefilefiif-d$HOME|-w$HOMEthenechothefileexistsandyoucanwirte$HOMEelseechoyoucantwritethefilefi双圆括号()表示数学表达式#!/bin/bashnum1=10if($num1*290)then(num2=$num1*2)echothesquareof$num1is$num2fi双方括号表示高级字符串处理函数使用双方括号可以定义与字符串值相匹配的正则表达式#!/bin/bashif$USER=s*thenechohello$USERelseechosorry,idontknowyouficase条件选择格式如下:casestringinexp-1)若干个命令行1;exp-2)若干个命令行2;*)其他命令行esacshell通过计算字符串string的值,将其结果依次和表达式exp-1、exp-2等进行比较,直到找到一个匹配的表达式为止,如果找到了匹配项则执行它下面的命令直到遇到一对分号(;)为止。在case表达式中也可以使用shell的通配符(“*”、“?”、“”)。通常用“*”作为case命令的最后表达式以便使在前面找不到任何相应的匹配项时执行“其他命令行”的命令。#!/bin/bashcase$USERinroot|testuser)echowelcome$USERechoyourareadmin;linuxidc)echowelcome$USER;*)echowelcome$USER;esacfor循环for循环对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。for循环的一般格式为:for变量名in数值列表do若干个命令行done变量名可以是用户选择的任何字符串,如果变量名是var,则在in之后给出的数值将顺序替换循环命令列表中的$var。如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。sgflocalhostsgf$cattest3#!/bin/bashfortestinCCNACCNPRHCEOCPOCMdoechothelearninglistis$testdonesgflocalhostsgf$./test3thelearninglistisCCNAthelearninglistisCCNPthelearninglistisRHCEthelearninglistisOCPthelearninglistisOCM#!/bin/bashforcitiesinguangzhoushanghaibeijingdoechomyfavoritecityis$citiesdone#!/bin/bashforcitiesinguangzhoushanghaibeijingdoechomyfavoritecityis$citiesdone#catsomefileaabbccdd#cattest3#!/bin/bashfile=somefileforwordsincat$filedoechothewordis$wordsdone执行后调用了somefile文件的每一行,注意somefile所处的位置是shell脚本中可以调用的,不然必须使用绝对路径或相对路径了#./test3thewordisaathewordisbbthewordisccthewordisdd使用通配符读取目录#pwd/home/sgf/test#touchaabbcc#mkdirddeeff先创建三个文件和三个目录#cattest3#!/bin/bashforfilein$HOME/test/*doif-d$filethenecho$fileisadirectoryelif-f$filethenecho$fileisafilefidone#./test3/home/sgf/test/aaisafile/home/sgf/test/bbisafile/home/sgf/test/ccisafile/home/sgf/test/ddisadirectory/home/sgf/test/eeisadirectory/home/sgf/test/ffisadirectoryC语言式的for命令#!/bin/bashfor(i=1;i=10;i+)doechothenextnumis$idonewhile和until循环while和until命令都是用命令的返回状态值来控制循环的。While循环的一般格式为:while若干个命令行1do若干个命令行2done#!/bin/bashvar=8while$var-gt0doecho$varvar=$var-1doneuntil格式如下:until若干个命令行1do若干个命令行2doneuntil循环和while循环的区别在于:while循环在条件为真时继续执行循环,而until则是在条件为假时继续执行循环。#!/bin/bashvar=24until$var-eq0doecho$varvar=$var-8done嵌套循环#!/bin/bashfor(a=1;a=3;a+)doechooutsideloopis$a:for(b=1;b=3;b+)doechoinsideloopis$b:donedone#!/bin/bashvar1=5while$var1-ge0doechoouterloopis:$var1for(var2=1;var23;var2+)doechoinnerloop:$var2donevar1=$var1-1done无条件控制语句break和continuebreak用于立即终止当前循环的执行,而contiune用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在do和done之间才有效。breakfor#!/bin/bashfornumin12345678910doif$num-eq5thenbreakfiechothenumis:$num;doneechotheforloopisover!breakwhile#!/bin/bashnum=1while$num-lt10doif$num-eq5thenbreakfiechothenumberis$numnum=$num+1doneechothewhileloopisover!continuefor#!/bin/bashfor(a=1;a或者追加,看如下例子:#!/bin/bashfor(a=1;anum.txt注意如果是通过windows的ftp把代码传到linux下,应该要改变文件的格式为unix,否则有可能不能正常运行dos文件转换成文件转换成 unix文件格式文件格式 方法是vitest.sh:setfileformat=unix:wq#bashtest.sh作业练习各种流程控制和条件判断语句