3.流程把持语句: if语句格局以下:
#if语句的前面是Shell下令,假如该下令实行乐成前往0,则实行then前面的下令。
ifcommand
then
command
command
fi
#用test下令测试厥后面expression的了局,假如为真,则实行then前面的下令。
iftestexpression
then
command
fi
#上面的格局和testexpression同等
if[string/numericexpression]
then
command
fi
#上面的两种格局也能够用于判别语句的前提表达式,并且它们也是今朝对照经常使用的两种。
if[[stringexpression]]
then
command
fi
if((numericexpression))#let表达式
then
command
fi
见以下示例: />cat>test1.sh#从下令行间接编纂test1.sh文件。 echo-e"AreyouOK(y/n)?c" readanswer #这里的$answer变量必需要用双引号扩住,不然判别将失利。当变量$answer即是y或Y时,撑持上面的echo下令。 if["$answer"=y-o"$answer"=Y] then echo"Gladtoseeit." fi CTRL+D />../test1.sh
AreyouOK(y/n)?y
Gladtoseeit.
下面的判别还能够交换为: />cat>test2.sh echo-e"AreyouOK(y/norMaybe)?c" readanswer #[[]]复合下令操纵符同意个中的表达式包括元字符,这里输出以y或Y开首的恣意单词,或Maybe都实行then前面的echo。 if[[$answer==[yY]*||$answer=Maybe]] then echo"Gladtohearit. fi CTRL+D />../test2.sh
AreyouOK(y/norMaybe)?yes
Gladtohearit.
上面的例子将利用Shell中的扩大通配形式。 />shopt-sextglob#翻开该扩大形式 />answer="notreally" />if[[$answer=[Nn]o?(way|treally)]] >then >echo"Iamsorry." >fi
Iamsorry.
关于本示例中的扩大通配符,这里必要给出一个详细的注释。[Nn]o婚配No或no,?(way|treally)则暗示0个或1个(way或treally),因而answer变量婚配的字符串为No、no、Notreally、notreally、Noway、noway。 上面的示例利用了let下令操纵符,如: />cat>test3.sh if(($#!=2))#同等于[$#-ne2] then echo"Usage:$0arg1arg2"1>&2 exit1#exit加入值为0-255之间,只要0暗示乐成。 fi if(($1<0||$1>30))#同等于[$1-lt0-o$1-gt30] then echo"arg1isoutofrange." exit2 fi if(($2<=20))#同等于[$2-le20] then echo"arg2isoutofrange." fi CTRL+D />sh./test3.sh
Usage:./test3.sharg1arg2 />echo$?#Shell剧本的加入值为exit的参数值。
1 />sh./test3.sh4030
arg1isoutofrange. />echo$?
2 上面的示例为怎样在if的前提表达式中查验空变量: />cat>test4.sh if["$name"=""]#双引号就暗示空字符串。 then echo"nameisnull." fi CTRL+D />../test4.sh
nameisnull.
if/elif/else语句的利用体例和if语句极其类似,信任有编程履历的人都不会生疏,这里就不再赘述了,其格局以下:
ifcommand
then
command
elifcommand
then
command
else
command
fi
见以下示例剧本: />cat>test5.sh echo-e"Howoldareyou?c" readage if[$age-lt0-o$age-gt120]#同等于((age<0||age>120)) then echo"Youaresoold." elif[$age-ge0-a$age-le12]#同等于((age>=0&&age<=12)) then echo"Youarechild." elif[$age-ge13-a$age-le19]#同等于((age>=13&&age<=19)) then echo"Youare13--19yearsold." elif[$age-ge20-a$age-le29]#同等于((age>=20&&age<=29)) then echo"Youare20--29yearsold." elif[$age-ge30-a$age-le39]#同等于((age>=30&&age<=39)) then echo"Youare30--39yearsold." else echo"Youareabove40." fi CTRL+D />../test5.sh
Howoldareyou?50
Youareabove40.
/>cat>mylist#机关数据文件 tom patty ann jake CTRL+D />cat>test8.sh #!/bin/sh forpersonin$(catmylist)#for将轮回读取catmylist下令的实行了局。 do echo"person=$person" done echo"outofforloop." CTRL+D />../test8.sh
person=tom
person=patty
person=ann
person=jake
outofforloop.
/>cat>test9.sh forfileintest[1-8].sh#for将读取test1-test8,后缀为.sh的文件 do if[-f$file]#判别文件在以后目次是不是存在。 then echo"$fileexists." fi done CTRL+D />../test9.sh
test2.shexists.
test3.shexists.
test4.shexists.
test5.shexists.
test6.shexists.
test7.shexists.
test8.shexists.
/>cat>test10.sh fornamein$*#读取剧本的下令行参数数组,还能够写成forname的简化情势。 do echo"Hi,$name" done CTRL+D />../test10.shstephenann
Hi,stephen
Hi,ann
while轮回声明格局:
whilecommand#假如command下令的实行了局为0,或前提判别为真时,实行轮回体内的下令。
do
command
done
见以下示例剧本: />cat>test1.sh num=0 while((num<10))#同等于[$num-lt10] do echo-n"$num" letnum+=1 done echo-e"
Heresoutofloop." CTRL+D />../test1.sh
0123456789
Heresoutofloop.
/>cat>test2.sh go=start echoTypeqtoquit. while[[-n$go]]#同等于[-n"$go"],如利用该作风,$go必要被双引号括起。 do echo-nHowareyou. readword if[[$word==[Qq]]]#同等于["$word"=Q-o"$word"=q] then echoBye. go=#将go变量的值置空。 fi done CTRL+D />../test2.sh
Howareyou.Hi
Howareyou.q
Bye.
until轮回声明格局:
untilcommand#其判别前提和while恰好相反,即command前往非0,或前提为假时实行轮回体内的下令。
do
command
done
见以下示例剧本: />cat>test3.sh untilwho|grepstephen#轮回体内的下令将被实行,直到stephen登录,即grep下令的前往值为0时才加入轮回。 do sleep1 echo"Stephenstilldoesntlogin." done CTRL+D
shift下令声明格局:shift[n]
shift下令用来把剧本的地位参数列表向左挪动指定的位数(n),假如shift没有参数,则将参数列表向左挪动一名。一旦移位产生,被移出列表的参数就被永久删除。一般在while轮回中,shift用来读取列表中的参数变量。
见以下示例剧本: />setstephenannsherylmark#设置4个参数变量。 />shift#向左挪动参数列表一次,将stephen移出参数列表。 />echo$*
annsherylmark />shift2#持续向左挪动两位,将sheryl和ann移出参数列表 />echo$*
mark />shift2#持续向左挪动两位,因为参数列表中只要mark了,因而本次挪动失利。 />echo$*
mark
/>cat>test4.sh while(($#>0))#同等于[$#-gt0] do echo$* shift done CTRL+D />../test4.shabcde
abcde
bcde
cde
de
e
break下令声明格局:break[n]
和C言语分歧的是,Shell中break下令照顾一个参数,便可以指定加入轮回的层数。假如没有指定,其举动和C言语一样,即加入最内层轮回。假如指定轮回的层数,则加入指定层数的轮回体。假如有3层嵌套轮回,个中最外层的为1,两头的为2,最内里的是3。
见以下示例剧本: />cat>test5.sh whiletrue do echo-n"Areyoureadytomoveon?" readanswer if[[$answer==[Yy]]] then break else echo"Comeon." fi done echo"Hereweare." CTRL+D />../test5.sh
Areyoureadytomoveon?y
Hereweare
continue下令声明格局:continue[n]
和C言语分歧的是,Shell中continue下令照顾一个参数,便可以跳转到指定层级的轮回顶部。假如没有指定,其举动和C言语一样,即跳转到最内层轮回的顶部。假如指定轮回的层数,则跳转到指定层级轮回的顶部。假如有3层嵌套轮回,个中最外层的为3,两头的为2,最内里的是1。 />catmaillist#测试数据文件maillist的内容为以下信息。
stephen
ann
sheryl
mark
/>cat>test6.sh fornamein$(catmaillist) do if[[$name==stephen]];then continue else echo"Hello,$name." fi done CTRL+D />../test6.sh
Hello,ann.
Hello,sheryl.
Hello,mark.
I/O从头定向和子Shell:
文件中的输出能够经由过程管道从头定向给一个轮回,输入也能够经由过程管道从头定向给一个文件。Shell启动一个子Shell来处置I/O从头定向和管道。在轮回停止时,轮回外部界说的任何变量关于剧本的其他局部来讲都是不成见的。 />cat>demodata#为上面的剧本机关测试数据
abc
def
ghi CRTL+D />cat>test7.sh if(($#<1))#假如剧本参数的数目小于1,则给堕落误提醒前进出。 then echo"Usage:$0filename">&2 exit1 fi count=1 cat$1|whilereadline#参数一中的文件被cat下令输入后,经由过程管道逐行输入给whilereadline。 do let$((count==1))&&echo"Processingfile$1...">/dev/tty#该行的echo将输入到以后终端窗口。 echo-e"$count $line"#将输入行号和文件中该行的内容,两头用制表符离隔。 letcount+=1 done>outfile#将while轮回中一切的输入,除>/dev/tty以外,别的的全体输入到outfile文件。 CTRL+D />../test7.shdemodata#只要一行输入,其他的都输入到outfile中了。
Processingfiledemodata... />catoutfile
1abc
2def
3ghi