Shell脚本编程基础知识_第1页
Shell脚本编程基础知识_第2页
Shell脚本编程基础知识_第3页
Shell脚本编程基础知识_第4页
Shell脚本编程基础知识_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux操作系统

Shell脚本编程2021/5/91主要内容和学习要求掌握创建shell

脚本的基本步骤学会使用条件测试掌握if

条件结构与case

选择结构掌握for

循环、while

循环和until

循环结构学会shift

命令的使用学会shell

脚本的调试2021/5/92

Shell

脚本Shell脚本如果有一系列你经常使用的Linux命令,你可以把它们存储在一个文件里,shell可以读取这个文件并顺序执行其中的命令,这样的文件被称为脚本文件。shell

脚本按行解释。2021/5/93

Shell脚本的编写

Shell

脚本是纯文本文件,可以使用任何文本编辑器编写

Shell

脚本通常是以.sh作为后缀名

Shell脚本的执行chmod

+x

script_name./script_namebash

script_name2021/5/94

第一行:指定用哪个程序来编译和执行脚本。

Shell脚本的格式#!/bin/bash可执行语句和shell

控制结构注释:以“#”开头,可独占一行,或跟在语句的后面。Shell脚本#!/bin/sh#!/bin/csh一个shell

脚本通常由一组Linux

命令、shell

命令、控制结构和注释语句构成。在脚本中多写注释语句是一个很好的编程习惯2021/5/95#!/bin/bash#ThisisthefirstBashshellprogram#ScriptName:greetings.shechoecho

–e"Hello$LOGNAME,\c"echo"it'snicetalkingtoyou."echo"Yourpresentworkingdirectoryis:"pwd#Showthenameofpresentdirectoryechoecho

–e"Thetimeis`date+%T`!.\nBye"echobash

greetings.shchmod+x

greetings.sh./greetingsShell脚本举例2021/5/96echo命令功能说明:显示文字。语法:echo[-ne][字符串]或echo[--help][--version]补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号。-n不进行换行-e若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出

\n换行\b空格...2021/5/97参数:-n不要在最后自动换行-e若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:\a发出警告声;\b删除前一个字符;\c最后不加上换行符号;\f换行但光标仍旧停留在原来的位置;\n换行且光标移至行首;\r光标移至行首,但不换行;\t插入tab;\v与\f相同;\\插入\字符;\nnn插入nnn(八进制)所代表的ASCII字符;--help显示帮助--version显示版本信息2021/5/98#!/bin/bash#Thisscriptistotesttheusageofread#Scriptname:ex4read.shecho"===examplesfortestingread==="echo-e

"Whatisyourname?\c"readnameecho"Hello$name"echoecho-n"Wheredoyouwork?"readecho"Iguess$REPLYkeepsyoubusy!"echoread-p

"Enteryourjobtitle:"#自动读给REPLYecho"Ithoughtyoumightbean$REPLY."echoecho"===Endofthescript==="Shell脚本举例2021/5/99read命令readvariable#读取变量给variablereadxy#可同时读取多个变量read#自动读给REPLYread–p“Pleaseinput:”

#自动读给REPLY2021/5/910状态变量$?中保存命令退出状态的值grep$USER

/etc/passwd

echo$?grephello

/etc/passwd;echo$?条件测试条件测试可以根据某个特定条件是否满足,来选择执行相应的任务。

Bash

中允许测试两种类型的条件:

命令成功或失败,表达式为真或假任何一种测试中,都要有退出状态(返回值),退出状态为0表示命令成功或表达式为真,非0则表示命令失败或表达式为假。2021/5/911

内置测试命令

test通常用test

命令来测试表达式的值x=5;y=10test$x

-gt

$yecho$?

test

命令可以用方括号来代替x=5;y=10[

$x

-gt$y]

echo$?

表达式测试包括字符串测试、整数测试和文件测试。测试表达式的值方括号前后要留空格!2021/5/912name=Tom

[$name

=[Tt]??

]

echo$?

2.x

版本以上的Bash

中可以用双方括号来测试表达式的值,此时可以使用通配符进行模式匹配。测试表达式的值[[$name

=[Tt]??

]]

echo$?2021/5/913字符串测试name=Tom;[-z$name];

echo$?操作符两边必须留空格!字符串测试name2=Andy;[$name

=$name2

]

;

echo$?2021/5/914

整数测试,即比较大小x=1;[$x

-eq

1

];

echo$?x=a;[$x

-eq

1

];

echo$?整数测试操作符两边必须留空格!X2021/5/915整数测试也可以使用let

命令或双圆括号x=1;let

"$x

==

1";

echo$?x=1;(($x+1>=2));

echo$?只能用于整数测试!整数测试相应的操作符为:==

、!=

、>

、>=

、<

、<=例:两种测试方法的区别使用的操作符不同

let

和双圆括号中可以使用算术表达式,而中括号不能

let

和双圆括号中,操作符两边可以不留空格2021/5/916逻辑测试x=1;name=Tom;[$x

-eq

1–a–n$name

];

echo$?逻辑测试注:不能随便添加括号[

(

$x

-eq

1

)–a(

–n$name

)

];

echo$?X2021/5/917x=1;name=Tom;[[$x

-eq

1&&$name=To?

]];

echo$?可以使用模式的逻辑测试逻辑测试2021/5/918文件测试:文件是否存在,文件属性,访问权限等。常见的文件测试操作符更多文件测试符参见test

的在线帮助mantest文件测试2021/5/919检查空值[

"$name"

=

""][!

"$name"][

"X${name}"

!=

"X"]检查空值2021/5/920语法结构ifexpr1#如果expr1为真(返回值为0)then#那么

commands1#执行语句块commands1elif

expr2#若expr1不真,而expr2为真then#那么

commands2#执行语句块commands2......

#可以有多个elif语句else#else最多只能有一个

commands4#执行语句块commands4fi#

if语句必须以单词fi

终止if条件语句2021/5/921

commands

为可执行语句块,如果为空,需使用shell

提供的空命令“:”,即冒号。该命令不做任何事情,只返回一个退出状态0

if

语句可以嵌套使用

ex4if.sh,chkperm.sh,chkperm2.sh,

name_grep,tellme,tellme2,idcheck.sh几点说明

elif

可以有任意多个(0个或多个)

else

最多只能有一个(0个或1个)

if

语句必须以fi

表示结束

expr

通常为条件测试表达式;也可以是多个命令,以最后一个命令的退出状态为条件值。2021/5/922ex4if.sh#!/bin/bash#scriptname:ex4if.sh#echo-n"Pleaseinputx,y:"readxyecho"x=$x,y=$y"if((x>y));thenecho"xislargerthany"elif((x==y));thenecho"xisequaltoy"elseecho"xislessthany"fi2021/5/923chkperm.sh#!/bin/bash#Usingtheoldstyletestcommand:[]#filename:perm_check.sh#file=testingif[-d$file]thenecho"$fileisadirectory"elif[-f$file]thenif[-r$file-a-w$file-a-x$file]then#nestedifcommandecho"Youhaveread,write,andexecutepermissionon$file."fielseecho"$fileisneitherafilenoradirectory."fi2021/5/924chkperm2.sh#!/bin/bash#Usingthenewstyletestcommand:[[]]#filename:perm_check2.sh#file=./testingif[[-d$file]]thenecho"$fileisadirectory"elif[[-f$file]]thenif[[-r$file&&-w$file&&-x$file]]then#nestedifcommandecho"Youhaveread,write,andexecutepermissionon$file."fielseecho"$fileisneitherafilenoradirectory."fi2021/5/925name_grep#!/bin/bash#filename:name_grep#name=Tomifgrep"$name"/etc/passwd>&/dev/nullthen:elseecho"$namenotfoundin/etc/passwd"exit2fi2021/5/926tellme#!/bin/bashecho-n"Howoldareyou?"readageif[$age-lt0-o$age-gt120]then echo"Welcometoourplanet!" exit1fiif[$age-ge0-a$age-le12]then echo"Childrenistheflowersofthecountry"elif[$age-gt12-a$age-le19]then echo"Rebelwithoutacause"elif[$age-gt19-a$age-le29]then echo"Yougottheworldbythetail!!"elif[$age-ge30-a$age-le39]then echo"Thirtysomething..."else echo"SorryIasked"fi2021/5/927tellme2#!/bin/bashecho-n"Howoldareyou?"readageif((age<0||age>120))then echo"Welcometoourplanet!" exit1fiif((age>=0&&age<=12))then echo"Childrenistheflowersofthecountry"elif((age>=13&&age<=19))thenecho"Rebelwithoutacause"elif((age>=19&&age<=29))then echo"Yougottheworldbythetail!!"elif((age>=30&&age<=39))then echo"Thirtysomething..."else echo"SorryIasked"fi2021/5/928idcheck.sh#!/bin/bash#Scriptname:idcheck.sh#purpose:checkuseridtoseeifuserisroot.#Onlyroothasauidof0.#Formatforidoutput:uid=501(tt)gid=501(tt)groups=501(tt)#root’suid=0:uid=0(root)gid=0(root)groups=0(root)…#id=`id|awk-F'[=(]''{print$2}'`#getuseridecho"youruseridis:$id"if((id==0))#[$id-eq0]then echo"youaresuperuser."else echo"youarenotsuperuser."fi2021/5/929语法结构caseexpr

in#expr

为表达式,关键词

in

不要忘!

pattern1)#若

expr

pattern1

匹配,注意括号

commands1#执行语句块

commands1;;#跳出

case

结构

pattern2)#若

expr

pattern2

匹配

commands2#执行语句块

commands2;;#跳出

case

结构

......

#可以有任意多个模式匹配

*)#若

expr

与上面的模式都不匹配

commands#执行语句块

commands;;#跳出

case

结构

esac#case

语句必须以

esac

终止case选择语句2021/5/930

case

语句举例:yes_no.sh几点说明每个命令块的最后必须有一个双分号,可以独占一行,或放在最后一个命令的后面。所给的匹配模式pattern

中可以含有通配符和“|”。如果expr

没有找到匹配的模式,则执行缺省值“*)”后面的命令块(类似于if

中的else);“*)”可以不出现。表达式expr

按顺序匹配每个模式,一旦有一个模式匹配成功,则执行该模式后面的所有命令,然后退出case。2021/5/931yes_no.sh#!/bin/bash#testcase#scriptname:yes_no.sh#echo-n"Doyouwishtoproceed[y/n]:"readanscase$ansiny|Y|yes|Yes)echo"yesisselected";;n|N|no|No)echo"noisselected" ;;*)echo"`basename$0`:Unknownresponse" exit1;;esac2021/5/932语法结构forvariable

in

list

#每一次循环,依次把列表

list

中的一个值赋给循环变量do#循环开始的标志

commands#循环变量每取一次值,循环体就执行一遍done#循环结束的标志几点说明列表list

可以是命令替换、变量名替换、字符串和文件名列表(可包含通配符)

for

循环执行的次数取决于列表list

中单词的个数

for

循环体中一般要出现循环变量,但也可以不出现for循环语句2021/5/933执行第一轮循环时,将list

中的第一个词赋给循环变量,并把该词从list

中删除,然后进入循环体,执行do和done

之间的命令。下一次进入循环体时,则将第二个词赋给循环变量,并把该词从list

中删除,再往后的循环也以此类推。当list

中的词全部被移走后,循环就结束了。循环执行过程forloop.sh,mybackup.sh

位置参量的使用:

$*与

$@

greet.sh

可以省略

inlist

,此时使用位置参量permx.shidcheck.shgreet.shyes_no.shpermx.sh*.shfor循环执行过程2021/5/934forloop.sh#!/bin/bash#Scriptname:forloop.shfornameinTomDickHarryJoedoecho"Hi$name"doneecho"outofloop"2021/5/935forloop2.sh#!/bin/bash#Scriptname:forloop2.shfornamein`catnamelist`doecho"Hi$name"doneecho"outofloop"2021/5/936mybackup.sh#!/bin/bash#Scriptname:mybackup.sh#Purpose:Createbackupfilesandstore#theminabackupdirectory.#backup_dir=backupmkdir$backup_dirforfilein*.shdoif[-f$file]thencp$file$backup_dir/${file}.bakecho"$fileisbackedupin$backup_dir"fidone2021/5/937greet.sh#!/bin/bash#Scriptname:greet.sh#usage:greet.shTomJohnAnndyecho"==using\$*=="fornamein$*#sameasfornamein$@doechoHi$namedoneecho"==using\$@=="fornamein$@#sameasfornamein$*doechoHi$namedoneecho'==using"$*"=='fornamein"$*"doechoHi$namedoneecho'==using"$@"=='fornamein"$@"doechoHi$namedone2021/5/938permx.sh#!/bin/bash#Scriptname:permx.sh#forfile#Emptywordlistdoif[[-f$file&&!-x$file]]thenchmod+x$fileecho"==$filenowhasexecutepermission"fidone2021/5/939语法结构whileexpr#执行

exprdo#若

expr

的退出状态为0,进入循环,否则退出whilecommands#循环体done#循环结束标志,返回循环顶部执行过程先执行expr,如果其退出状态为0,就执行循环体。执行到关键字done

后,回到循环的顶部,while

命令再次检查expr

的退出状态。以此类推,循环将一直继续下去,直到expr

的退出状态非0为止。while循环语句2021/5/940语法结构untilexpr#执行exprdo#若expr的退出状态非0,进入循环,否则退出untilcommands#循环体done#循环结束标志,返回循环顶部执行过程与while

循环类似,只是当expr

退出状态非0时才执行循环体,直到expr

为0时退出循环。until循环语句2021/5/941用于强行退出当前循环。如果是嵌套循环,则break

命令后面可以跟一数字n,表示退出第n

重循环(最里面的为第一重循环)。用于忽略本次循环的剩余部分,回到循环的顶部,继续下一次循环。如果是嵌套循环,continue

命令后面也可跟一数字n,表示回到第n

重循环的顶部。break

[n]continue

[n]例:months.shbreak和continue2021/5/942months.sh#!/bin/bash#Scriptname:months.shformonthinJanFebMarAprMayJunJulAugSepOctNovDecdoforweekin1234doecho-n"Processingthemonthof$month.OK?"readansif["$ans"=n-o-z"$ans"]thencontinue2else2021/5/943echo-n"Processweek$weekof$month?"readansif["$ans"=n-o-z"$ans"]thencontinueelseecho"Nowprocessingweek$weekof$month."sleep1#Commandsgohereecho"Doneprocessing..."fifidonedone2021/5/944sleepnexit和sleepexitnexit

命令用于退出脚本或当前进程。n

是一个从0到255的整数,0表示成功退出,非零表示遇到某种失败而非正常退出。该整数被保存在状态变量$?中。

exit

命令

sleep

命令暂停n

秒钟2021/5/945语法结构说明

select

循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3

提示符,等待用户输入用户输入菜单列表中的某个数字,执行相应的命令用户输入被保存在内置变量REPLY

中。selectvariable

in

list

do#循环开始的标志

commands#循环变量每取一次值,循环体就执行一遍done#循环结束的标志例:runit.shselect循环与菜单2021/5/946runit.sh#!/bin/bash#Scriptname:runit.shPS3="Selectaprogramtoexecute:"selectprogramin'ls-F'pwddatedo $programdone2021/5/947例:goodboy.sh

select

经常和case

联合使用

select

是个无限循环,因此要记住用break

命令退出循环,或用exit

命令终止脚本。也可以按ctrl+c

退出循环。与for

循环类似,可以省略inlist

,此时使用位置参量select与case2021/5/948goodboy.sh#!/bin/bash#Scriptname:goodboys.shPS3="Pleasechooseoneofthethreeboys:"selectchoiceintomdanguy#selectchoicedocase$choiceintom)echoTomisacooldude!break;; #breakoutoftheselectloopdan|guy)echoDanandGuyarebothwonderful.break;;*)echo"$REPLYisnotoneofyourchoices"echo"Tryagain.";;esacdone2021/5/949shift

[n]用于将参量列表list

左移指定次数,缺省为左移一次。参量列表list

一旦被移动,最左端的那个参数就从列表中删除。while

循环遍历位置参量列表时,常用到shift。./doit.shabcdefgh./shft.shabcdefgh循环控制shift命令例:2021/5/950doit.sh#!/bin/bash#Name:doit.sh#Purpose:shiftthroughcommandlinearguments#Usage:doit.sh[args]while(($#>0))#or[$#-gt0]doecho$*shiftdone2021/5/951shft.sh#!/bin/bash#Using'shift'tostepthroughallthepositionalparameters.until[-z"$1"]#Untilallparametersusedup...doecho"$1"shiftdoneecho#Extralinefeed.exit02021/5/952

生成随机数的特殊变量echo$RANDOM范围是:[0,32767]

expr:通用的表达式计算命令表达式中参数与操作符必须以空格分开,表达式中的运算可以是算术运算,比较运算,字符串运算和逻辑运算。expr5%3expr5\*3#乘法符号必须被转义随机数和expr命令2021/5/953字符串操作注:pattern,old中可以使用通配符。例:ex4strm的取值从0到${#var}-1字符串操作2021/5/954ex4str#!/bin/bashdirname="/usr/bin/local/bin";echo"dirname=$dirname"echo-n'${#dirname}=';sleep4;echo"${#dirname}"echoecho-n'${dirname:4}=';sleep4;echo"${dirname:4}"echoecho-n'${dirname:8:6}=';sleep4;echo${dirname:8:6}echoecho-n'${dirname#*bin}=';sleep4;echo${dirname#*bin}echoecho-n'${dirname##*bin}=';sleep4;echo${dirname##*bin}echoecho-n'${dirname%bin}=';sleep4;echo${dirname%bin}echoecho-n'${dirname%%bin}=';sleep4;echo${dirname%%bin}echoecho-n'${dirname%bin*}=';sleep4;echo${dirname%bin*}echoecho-n'${dirname%%bin*}=';echo${dirname%%bin*}echoecho-n'${dirname/bin/sbin}=';echo${dirname/bin/sbin}echoecho-n'${dirname//bin/lib}=';echo${dirname//bin/lib}echoecho-n'${dirname/bin*/lib}=';echo${dirname/bin*/lib}2021/5/955sh

–x

脚本名该选项可以使用户跟踪脚本的执行,此时shell

对脚本中每条命令的处理过程为:先执行替换,然后显示,再执行它。shell

显示脚本中的行时,会在行首添加一个加号“+”。sh–v

脚本名在执行脚本之前,按输入的原样打印脚本中的各行,打印一行执行一行。sh–n

脚本名对脚本进行语法检查,但不执行脚本。如果存在语法错误,shell

会报错,如果没有错误,则不显示任何内容。脚本调试2021/5/956编程小结:变量局部变量、环境变量(export、declare-x)只读变量、整型变量例:declare

-ix;x="hello";

echo$x0位置参量($0,$1,...,$*,$@,$#,$$,$?)变量的间接引用(eval,

${!str})例:name="hello";x="name";

echo${!x}hello命令替换(`cmd`、$(cmd))整数运算

declare

定义的整型变量可以直接进行运算,

否则需用let

命令或$[...]、$((...))进行整数运算。2021/5/957编程小结:输入输出

输入:readreadvar1var2...readread–p

"提示"输出:printfprintf"%-12.5f\t%d\n"123.458format

以%开头flagfieldwidthprecision格式符-:左对齐+:输出符号0:空白处添0空格:前面加一空格字段宽度小数点后输出位数cdefgsox\b\n\r\t\v\\\”%%REPLYREPLY输出参数用空格隔开2021/5/958字符串测试编程小结:条件测试操作符两边必须留空格!如果使用双方括号,可以使用通配符进行模式匹配。例:name=Tom;[[$name>Tom]];

echo$?2021/5/959编程小结:条件测试整数测试注意这两种方法的区别!2021/5/960编程小结:条件测试逻辑测试如果使用双方括号,可以使用通配符进行模式匹配。2021/5/961编程小结:条件测试文件测试2021/5/962编程小结:控制结构

if

条件语句

case

选择语句

for

循环语句

while

循环语句

until

循环语句

break、continue、sleep

命令

select循环与菜单

shift命令

${...},$(...),$[...],$((...))[...],[[...]],((...))各种括号的作用2021/5/963function_name(){commands}函数

一个函数就是一个子程序,用于完成特定的任务,当有重复代码,或者一个任务只需要很少的修改就被重复几次执行时,这时你应考虑使用函数。functionfunction_name{commands}

函数的一般格式

和其它编程语言一样,Bash也可以定义函数。2021/5/964函数举例#!/bin/bashfun1(){echo"Thisisafunction"echo

"Nowexitingfun1."

}fun2(){echo"Thisisfun2."echo"Nowexitingfun2."}2021/5/965

只需输入函数名即可调用该函数。函数的调用

函数必须在调用之前定义#!/bin/bashfun2(){echo"Thisisfun2."echo"Nowexitingfun2."}fun2#调用函数

fun2例:ex4fun2.sh,ex4fun3.sh2021/5/966ex4fun2.sh#!/bin/bashJUST_A_SECOND=1fun(){#Asomewhatmorecomplexfunctioni=0REPEATS=5echoecho"Andnowthefunreallybegins."echosleep$JUST_A_SECOND#Hey,waitasecond!while[$i-lt$REPEATS]doecho"----------FUNCTIONS---------->"echo"<------------ARE-------------"echo"<------------FUN------------>"echolet"i+=1"done}#Now,callthefunctions.funexit02021/5/967ex4fun3.sh#f1#Willgiveanerrormessage,sincefunction"f1"notyetdefined.#declare-ff1#Thisdoesn'thelpeither.#f1#Stillanerrormessage.#However...f1(){echo"Callingfunction\"f2\"fromwithinfunction\"f1\"."f2}f2(){echo"Function\"f2\"."}#f1#Function"f2"isnotactuallycalleduntilthispoint#althoughitisreferencedbeforeits

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论