版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章
bash脚本编程本章内容要点Shell脚本的编制、执行和调试Shell脚本的成分和编码规范Shell变量替换扩展、数值计算、输入输出变量分类,位置参数变量和特殊参数变量条件测试(文件测试、字符串测试、整数测试)分支流程控制(if、case)循环流程控制(for、while、until、select)函数的定义和调用、返回值使用循环分析命令行参数2024年5月29日2CreativeCommonsLicense(BY-NC-SA)本章学习目标熟悉Shell脚本的编码规范,掌握执行和调试方法掌握对变量进行整数运算和间接引用的方法理解位置参数变量和特殊参数变量的用途掌握条件测试的使用[]、[[]]、(())掌握各种流程控制语句的使用if、casefor、while、until、select、break、continue掌握函数的定义、调用和传递返回值的方法掌握命令行参数、位置参数的操作(shift、getopts)2024年5月29日3CreativeCommonsLicense(BY-NC-SA)Shell编程基础2024年5月29日4CreativeCommonsLicense(BY-NC-SA)Shell脚本和Shell编程当命令不在命令行中执行,而是从一个文件中执行时,该文件就称为Shell脚本。Shell脚本是纯文本文件。Shell脚本通常以.sh作为后缀名,但不是必须。Shell脚本是以行为单位的,在执行脚本的时候会分解成一行一行依次执行。Shell是一种功能强大的解释型编程语言通常用于完成特定的、较复杂的系统管理任务Shell脚本语言非常擅长处理文本类型的数据2024年5月29日CreativeCommonsLicense(BY-NC-SA)5Shell脚本的成分程序元素保留字、运算符、表达式变量、数组、输入输出控制结构(顺序、分支、循环、子程序调用)Shell功能
【参见第2、3章内容】执行命令(内置命令、外部命令、自编程序)重定向、管道、命令替换、命令聚合通配符、注释符、……Shell环境2024年5月29日CreativeCommonsLicense(BY-NC-SA)6Shell脚本的建立与执行Shell脚本的建立使用文本编辑器编辑脚本文件$viscript-file为脚本文件添加可执行权限$chmod+xscript-fileShell脚本的执行在子Shell中执行$bashscript-file$script-file在当前Shell中执行$sourcescript-file$.script-file2024年5月29日CreativeCommonsLicense(BY-NC-SA)7PATH环境变量的默认值不包含当前目录,若脚本文件在当前目录,应使用./script-filePATH环境变量的默认值包含~/bin目录,用户可以将自己的脚本文件存放在~/bin目录,之后即可直接调用脚本文件名执行脚本了Shell脚本的编码规范以#!开头:通知系统用何解释器执行此脚本#!/bin/bash#!/bin/ksh以注释形式说明如下的内容:#脚本名称#脚本功能#作者及联系方式#版本更新记录#版权声明#对算法做简要说明(如果是复杂脚本)2024年5月29日CreativeCommonsLicense(BY-NC-SA)8Shell脚本举例(1)2024年5月29日CreativeCommonsLicense(BY-NC-SA)9#!/bin/bash#ThisisthefirstBashshellprogram#Scriptname:greetings.shechoecho
-e"Hello$LOGNAME,\c"echo"it'snicetalkingtoyou."echo
-n"Yourpresentworkingdirectoryis:"pwd#Showthenameofpresentdirectoryechoecho
-e"Thetimeis`date+%T`!.\nBye"echoShell脚本举例(2)2024年5月29日CreativeCommonsLicense(BY-NC-SA)10#!/bin/bash##ScriptName:/etc/cron.daily/ntpdate#使用NTP的客户端命令ntpdate与远程NTP服务器进行同步#也可以用局域网内的NTP服务器替换/usr/sbin/ntpdate-s#更改硬件时钟时都会记录在/etc/adjtime文件中#使hwclock根据先前的记录来估算硬件时钟的偏差,#并用来校正目前的硬件时钟/sbin/hwclock--adjust#将系统时钟同步到硬件时钟/sbin/hwclock–systohc脚本调试方法在bash调用脚本时使用参数$bash[-x][-n][-v]scriptName在脚本中使用bash内置的
set命令使整个或部分脚本处于调试模式开启:set[-x][-n][-v]结束:set[+x][+n][+v]2024年5月29日CreativeCommonsLicense(BY-NC-SA)11脚本调试12024年5月29日CreativeCommonsLicense(BY-NC-SA)12sh
–x
脚本名该选项可以使用户跟踪脚本的执行,此时shell
对脚本中每条命令的处理过程为:先执行替换,然后显示,再执行它。shell
显示脚本中的行时,会在行首添加一个加号“+”。sh–v
脚本名在执行脚本之前,按输入的原样打印脚本中的各行。sh–n
脚本名对脚本进行语法检查,但不执行脚本。如果存在语法错误,shell
会报错,如果没有错误,则不显示任何内容。脚本调试举例1对脚本进行语法检查$bash-ngreetings.sh显示脚本中每个原始命令行及其执行结果$bash-vgreetings.sh以调试模式执行脚本$bash-xgreetings.sh2024年5月29日CreativeCommonsLicense(BY-NC-SA)13脚本调试2——set命令在脚本内使用set命令开启调试选项set-x:显示由shell执行的命令及其参数set-v:显示由shell读入的命令行set-n
:读取命令但不执行他们,用于语法检查在脚本内使用set命令关闭已开启的调试选项set+xset+vset+n2024年5月29日CreativeCommonsLicense(BY-NC-SA)14脚本调试举例2$bashgreetings.sh./greetings.sh$sourcegreetings.sh2024年5月29日CreativeCommonsLicense(BY-NC-SA)15#!/bin/bash#ThisisthefirstBashshellprogram#Scriptname:greetings.shset-x###TurnONdebugmode###echoecho-e"Hello$LOGNAME,\c"echo"it'snicetalkingtoyou."echo-n"Yourpresentworkingdirectoryis:"pwd#Showthenameofpresentdirectoryechoset+x###TurnOFFdebugmode###echo-e"Thetimeis`date+%T`!.\nBye"echoShell脚本的类型非交互式脚本不需要读取用户的输入,也不用向用户反馈某些信息每次执行都是可预见的,因为它不读取用户输入,参数是固定的可以在后台执行交互式脚本脚本可以读取用户的输入,实时向用户反馈信息(输出某些信息)这样的脚本更灵活,每次执行时的参数可由用户动态设定用户界面更友好,但不适用于自动化任务(如cron任务)2024年5月29日CreativeCommonsLicense(BY-NC-SA)16学习Shell编程的前提掌握一种文本编辑器的使用(Vi)熟悉Linux文件系统的布局学习Shell的各种功能重定向、管道、命令替换、命令聚合学习各种管理和监视命令的使用用户管理、权限管理、进程管理、包管理……系统监视、网络监视……学习各种文本文件工具的使用cat、grep、tr、sed、awk……正则表达式2024年5月29日CreativeCommonsLicense(BY-NC-SA)17系统的配置文件几乎都是纯文本文件变量和表达式2024年5月29日18CreativeCommonsLicense(BY-NC-SA)Shell变量操作变量替换扩展变量测试变量的字符串操作变量的间接引用变量的数值计算$[expression]$((expression))exprletdeclare-i2024年5月29日CreativeCommonsLicense(BY-NC-SA)19输入变量赋值name=valuereadonly从标准输入读取read输出echoprintf变量替换扩展——变量测试2024年5月29日CreativeCommonsLicense(BY-NC-SA)20UseDefaultValues${var:-word}若var存在且非空,则值为$var;若var未定义或为空值,则值为word,但var的值不变。AssignDefaultValues${var:=word}若var存在且非空,则值为$var;若var未定义或为空值,则值为word,且var被赋值word。DisplayErrorifNullorUnset${var:?word}若var存在且非空,则值为$var;若var未定义或为空值,则输出信息word,并终止脚本。UseAlternateValue${var:+word}若var存在且非空,则值为word;否则返回空值,但var的值不变。变量测试举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)21color=bluenewcolor=${color:-grey}unsetcolorecho"Theskyis${color:-grey}today"echo
$colorecho"Theskyis${color:=grey}today"echo
$colorecho"Theskyis${color:?error}today"echo
$colorecho"Theskyis${color:+blue}today"echo
$color变量替换扩展
——字符串计数、截取2024年5月29日CreativeCommonsLicense(BY-NC-SA)22${#var}返回字符串变量var
的长度${var:m}返回${var}中从第m个字符到最后的部分${var:m:len}返回${var}中从第m个字符开始,长度为len的部分${var#pattern}删除${var}中开头部分与pattern匹配的最小部分${var##pattern}删除${var}中开头部分与pattern匹配的最大部分${var%pattern}删除${var}中结尾部分与pattern匹配的最小部分${var%%pattern}删除${var}中结尾部分与pattern匹配的最大部分m的取值从0到${#var}-1注:pattern中可以使用通配符。字符串变量替换扩展举例12024年5月29日CreativeCommonsLicense(BY-NC-SA)23str='Ilovelinux.IloveUNIXtoo.’echo${#str}30echo${#str:13}IloveUNIXtoo.echo
${#str:7:5}linuxecho
${str#Ilove}linux.IloveUNIXtoo.echo
${str#I*.}IloveUNIXtoo.echo
${str##I*}
变量替换扩展
——字符串替换2024年5月29日CreativeCommonsLicense(BY-NC-SA)24${var/old/new}用new替换${var}中第一次出现的old${var//old/new}用new替换${var}中所有的old(全局替换)${var/#old/new}用new替换${var}中开头部分与old匹配的部分${var/%old/new}用new替换${var}中结尾部分与old匹配的部分注:(1)old
中可以使用通配符。(2)var可以是@
或*,表示对每个位置参数进行替换字符串变量替换扩展举例22024年5月29日CreativeCommonsLicense(BY-NC-SA)25str='Ilovelinux.IloveUNIXtoo.’echo${str/love/like}Ilikelinux.IloveUNIXtoo.echo${str//love/like}Ilikelinux.IlikeUNIXtoo.echo
${str/I*linux/IlikeFreeBSD}IlikeFreeBSD.IloveUNIXtoo.echo${str/#Ilove/"J'aime"}J'aimelinux.IloveUNIXtoo.echo${str//Ilove/"J'aime"}J'aimelinux.J'aimeUNIXtoo.echo
${str/%too./also.}Ilovelinux.IloveUNIXalso.字符串变量替换扩展举例32024年5月29日CreativeCommonsLicense(BY-NC-SA)26set1v11v21v31v4echo
$@1v11v21v31v4echo
${@/1/a}av1av2av3av4echo
${@//1/a}avaav2av3av4echo${@/%1/a}1va1v21v31v4变量的间接引用通过str2
的值来引用str1
的值2024年5月29日CreativeCommonsLicense(BY-NC-SA)27str1="HelloWorld"str2=str1echo
$str2#bash2.0以上才支持newstr=${!str2}echo$newstrHelloWorld或echo${!str2}HelloWorld
evalnewstr=\$$str2echo$newstrHelloWorld或evalecho\$$str2HelloWorld
?变量的间接引用(续)2024年5月29日CreativeCommonsLicense(BY-NC-SA)28通过x
的值来引用CENTOS_URL
的值x="CENTOS"CENTOS_URL="/centos/"#bash2.0以上才支持newstr=${x}_URLecho$newstrCENTOS_URLecho${!newstr}/centos/evalnewstr=\$${x}_URLecho$newstr或evalecho\$${x}_URLShell内置命令——eval2024年5月29日CreativeCommonsLicense(BY-NC-SA)29listpage="ls-l|more"eval
$listpageeval$(ssh-agent)evalnewstr=\$$str2evalecho\$${x}_URL
evalarg1[arg2]...[argN]对参数进行两次扫描和替换将所有的参数连接成一个表达式,并计算或执行该表达式参数中的任何变量都将被展开Shell变量的分类用户自定义变量由用户自己定义、修改和使用Shell环境变量由系统维护,用于设置用户的Shell工作环境只有少数的变量用户可以修改其值位置参数变量(PositionalParameters)通过命令行给程序传递执行参数可用shift命令实现位置参数的迁移专用参数变量(SpecialParameters)Bash预定义的特殊变量用户不能修改其值2024年5月29日CreativeCommonsLicense(BY-NC-SA)30位置参数变量是一组特殊的内置变量跟在脚本名后面的用空格隔开的每个字符串$1表示第1个参数值,……,$9表示第9个参数值${10}表示第10个参数值,${11}表示第11个参数值,……位置参数的用途从shell命令/脚本的命令行接受参数在调用shell函数时为其传递参数2024年5月29日CreativeCommonsLicense(BY-NC-SA)31专用参数变量命令行参数相关$*将所有位置参量看成一个字符串(以空格间隔)。$@将每个位置参量看成单独的字符串(以空格间隔)。“$*”将所有位置参量看成一个字符串(以$IFS间隔)。“$@”将每个位置参量看成单独的字符串(以空格间隔)。$0命令行上输入的Shell程序名。$#
表示命令行上参数的个数。进程状态相关$?
表示上一条命令执行后的返回值$$
当前进程的进程号$!
显示运行在后台的最后一个作业的PID$_
在此之前执行的命令或脚本的最后一个参数2024年5月29日CreativeCommonsLicense(BY-NC-SA)32位置参数和专用参数举例执行脚本$./vartest.sh1‘23’45abcdefg2024年5月29日CreativeCommonsLicense(BY-NC-SA)33#!/bin/bash#ScriptName:vartest.sh#TotestPositionalParameters&SpecialParameters.echo"Hello,$USER,theoutputofthisscriptareasfollows:"echo"Thescriptnameis:$(basename$0)"echo"Thefirstparamofthescriptis:$1"echo"Thesecondparamofthescriptis:$2"echo"Thetenthparamofthescriptis:${10}"echo"Alltheparamsyouinputare:$@"echo"Alltheparamsyouinputare:$*"echo"Thenumberoftheparamsyouinputare:$#"echo"TheprocessIDforthisscriptis:$$"echo"Theexitstatusofthisscriptis:$?”$@、$*和环境变量IFS2024年5月29日CreativeCommonsLicense(BY-NC-SA)34执行脚本$./ifsargs.sh1‘23’45abcdefg#!/bin/bash#ScriptName:ifsargs.sh####SettheIFSto|####IFS='|'echo"Command-LineArgumentsDemo"echo"*Allargsdisplayedusing\$@positionalparameter*"echo$@echo"*Allargsdisplayedusing\$*positionalparameter*"echo$*echo'*Allargsdisplayedusing"$@"positionalparameter*'echo"$@"#***doublequoteadded***#echo'*Allargsdisplayedusing"$*"positionalparameter*'echo"$*"#***doublequoteadded***#位置参数和shift命令将位置参量列表依次左移n次,缺省为左移一次一旦位置参量列表被移动,最左端的那个参数就会从列表中删除经常与循环结构语句一起使用,以便遍历每一个位置参数2024年5月29日CreativeCommonsLicense(BY-NC-SA)35shift
[n]#!/bin/sh#ScriptName:pp_shift.sh#TotestPositionalParameters&Shift.echo"Thescriptnameis:$0"echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"shift#向左移动所有的位置参数1次echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"shift2#向左移动所有的位置参数2次echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"$./pp_shift.sh1b3d4f退出/返回状态$?:返回上一条语句或脚本执行的状态0:成功1-255:不成功exit
命令exit
命令用于退出脚本或当前Shell
n
是一个从0到255的整数0表示成功退出,非零表示遇到某种失败返回值被保存在状态变量$?
中2024年5月29日CreativeCommonsLicense(BY-NC-SA)36exitn常见的返回状态码0:执行正确1:通用错误126:命令或脚本没有执行权限127:命令没找到2024年5月29日CreativeCommonsLicense(BY-NC-SA)37$echo$$#显示当前进程的PID9245$echo$?#显示在此之前执行的命令的返回值0$bash#调用子Shell$echo$$#显示当前进程的PID9474$exit1#指定返回值并返回父Shell$echo$?#显示上一个Shell/脚本的返回值1$list#执行不存在的命令bash:list:commandnotfound$echo$?127$touchbbb.sh$./bbb.sh#执行不具有执行权限的命令bash:./bbb.sh:Permissiondenied$echo$?126read从键盘输入内容为变量赋值read[-p
"信息"][var1var2...]若省略变量名,则将输入的内容存入REPLY变量结合不同的引号为变量赋值双引号””:允许通过$符号引用其他变量值单引号’’:禁止引用其他变量值,$视为普通字符反撇号
``
:将命令执行的结果输出给变量更多read的用法参见/guide/Getting_User_Input_Via_Keyboard2024年5月29日CreativeCommonsLicense(BY-NC-SA)38read举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)39#!/bin/bash#Thisscriptistotesttheusageofread#Scriptname:ex4read.shecho"===examplesfortestingread==="echo-e
"Whatisyourname?\c"readnameecho"Hello$name"echoecho-n"Wheredoyouwork?"readecho"Iguess$REPLYkeepsyoubusy!"echoread-p
"Enteryourjobtitle:"echo"Ithoughtyoumightbean$REPLY."echoecho"===Endofthescript==="只读变量举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)40只读变量readonlyvariable是指不能被清除或重新赋值的变量。[lrj@centos1~]$myname=Osmond[lrj@centos1~]$echo$mynameOsmond[lrj@centos1~]$readonlymyname[lrj@centos1~]$unsetmyname-bash:unset:myname:cannotunset:readonlyvariable[lrj@centos1~]$myname="OsmondLiang"-bash:myname:readonlyvariable[lrj@centos1~]$同时输出多行信息使用echo使用herefile2024年5月29日CreativeCommonsLicense(BY-NC-SA)41echo
"Line1Line2Line3"cat<<_END_Line1Line2Line3_END_多行内容中不能出现双引号,否则echo
提前结束若确实需要使用双引号,需使用转义字符:\"_END_可以是任意字符串,只要上下一致即可多行内容中不能出现内容为_END_开始的行,否则cat提前结束整数运算Bash变量没有严格的类型定义本质上Bash变量都是字符串若一个字面常量或变量的值是纯数字的,不包含字母或其他字符,Bash可以将其视为长整型值,并可做算数运算和比较运算。Bash也允许显式地声明整型变量declare-i变量名2024年5月29日CreativeCommonsLicense(BY-NC-SA)42算数运算符2024年5月29日CreativeCommonsLicense(BY-NC-SA)43+、-、*、/(四则运算)**、%(幂运算和模运算,取余数)<<、>>(按位左移和按位右移)&、^、|(按位与、按位异或和按位或)=、+=、-=、*=、/=、%=
<<=、>>=、&=、^=、|=(赋值运算)<、>、<=、>=、==、!=(比较操作符)&&、||(逻辑与和逻辑或)注:按位运算是以二进制形式进行的。算术运算扩展2024年5月29日CreativeCommonsLicense(BY-NC-SA)44$[expression]
$((expression))num1=$[4+1];echo
$num1num1=$(($num1*2-3));echo
$num1注意${···},$(···),$[···],$((···))
的不同作用用$[···],$((···))
进行整数运算时,括号内变量前的美元符号$可以省略。((num2=2+3**2-1001%5));echo
$num2num2=$((2+3**2-1001%5));echo
$num2echo
$((2+3**2-1001%5))Shell内置命令——letlet内置命令用于算术运算2024年5月29日CreativeCommonsLicense(BY-NC-SA)45num2=1;echo
$num2letnum2=4+1;echo
$num2letnum2=$num2+1;echo
$num2赋值符号和运算符两边不能留空格!如果将字符串赋值给一个整型变量时,则变量的值为0如果变量的值是字符串,则进行算术运算时设为0letnum2=4+1let"num2=4+1"#
用引号忽略空格的特殊含义用let
命令进行算术运算时,最好加双引号。expr通用的表达式计算命令表达式中参数与操作符必须以空格分开。表达式中的运算可以是算术运算,比较运算,字符串运算和逻辑运算。2024年5月29日CreativeCommonsLicense(BY-NC-SA)46manexprexpr5%3expr5\*3#乘法符号必须被转义expr2+5\*2-3%2expr
\(2+5\)\*2–3#括号必须被转义浮点数运算bash
只支持整数运算可以通过使用bc
或
awk
工具来处理浮点数运算2024年5月29日CreativeCommonsLicense(BY-NC-SA)47n=$(echo"scale=3;13/2"|bc)echo
$nm=`awk'BEGIN{x=2.45;y=3.123;\printf"%.3f\n",x*y}'`echo
$mprintf命令2024年5月29日CreativeCommonsLicense(BY-NC-SA)48
printf
可用来按指定的格式输出变量printfformat输出参数列表printf"%-12.5f\n"123.456format
以%开头flagfieldwidthprecision格式符-:左对齐+:输出符号0:空白处添0空格:前面加一空格字段宽度小数点后输出位数printf命令(续)2024年5月29日CreativeCommonsLicense(BY-NC-SA)49printf
命令的格式说明符c字符型g/G浮点数(自动)d十进制整数o八进制e/E浮点数(科学计数法)s字符串f浮点数(小数形式)x/X十六进制format
中还可以使用\a警铃\t水平制表符\b退后一格\v垂直制表符\n换行\\反斜杠\f换页\”双引号\r回车%%百分号printf命令举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)50printf"Thenumberis:%.2f\n"100printf"%-20s|%12.5f|\n""Joy"10printf"%-10d%010o%+10x\n"202020printf"%6d\t%6o\"%6x\"\n"202020例:数组变量2024年5月29日CreativeCommonsLicense(BY-NC-SA)51
Bash
2.x
以上支持一维数组,下标从0开始。variable=(item1item2item2...)variable[n]=valuedeclare
-a
variablevariable=(item1item2item2...)数组的引用${variable[n]}使用declare
声明或直接给变量名加下标来赋值。数组变量举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)52declare
-a
stustu=(math1101math1102math1103)echo${stu[0]}
#列出stu的第一个元素echo${stu[*]}
#列出stu的所有元素echo${#stu[*]}
#给出数组stu中元素的个数数组与数组元素的删除unsetstu[1]#删除stu的第二个元素unsetstu#删除整个数组数组赋值时无须按顺序赋值x[3]=100;echo${x[*]}state=(ME[3]=CA[2]=NT);echo${state[*]}Shell内置命令——declare2024年5月29日CreativeCommonsLicense(BY-NC-SA)53内置命令declare可用来声明变量。declare[选项]
variable[=value]选项含义-r将变量设为只读(
readonly
)-x将变量输出到子shell中(export
为全局变量)-i将变量设为整型(integer
)-a将变量设置为一个数组(array
)-f列出函数的名字和定义(
function
)-F只列出函数名declare举例2024年5月29日CreativeCommonsLicense(BY-NC-SA)54declare–r
myname=osmondunsetmynamedeclaremyname=“OsmondLiang"declare–x
myname2=lrjmyname2=lrjdeclare–x
myname2declaredeclaremyname=osmond例:变量及相关命令小结12024年5月29日CreativeCommonsLicense(BY-NC-SA)55echo$variable
或echo${variable}unset
variablesetreadonlyvariableexportvariable=valueexport-nvariableexport-pdeclare[选项]
variable=value变量及相关命令小结22024年5月29日CreativeCommonsLicense(BY-NC-SA)56basenamedirnamelet或expr${var:-word}、${var:=word}、${var:?word}、${var:+word}$0、$1-$9、${n}、$#、$*、$@、$$、$!、$?、$-evalnewstr=\$$str2
、newstr=${!str2}`hostname`、$(hostname)`basename\`pwd\``、$(basename$(pwd))$[expression]
、$((expression))变量及相关命令小结32024年5月29日CreativeCommonsLicense(BY-NC-SA)57
输入readvar1var2...readread–p
"提示"输出printf"%-12.5f\t%d\n"123.458format
以%开头flagfieldwidthprecision格式符-:左对齐+:输出符号0:空白处添0空格:前面加一空格字段宽度小数点后输出位数cdefgsox\b\n\r\t\v\\\”%%
REPLY
REPLY输出参数用空格隔开条件测试2024年5月29日58CreativeCommonsLicense(BY-NC-SA)条件测试简介条件测试可以判断某个特定条件是否满足测试之后通常会根据不同的测试值选择执行不同任务条件测试的种类命令成功或失败表达式为真或假条件测试的值Bash中没有布尔类型变量退出状态为0表示命令成功或表达式为真非0则表示命令失败或表达式为假状态变量$?
中保存了退出状态的值2024年5月29日CreativeCommonsLicense(BY-NC-SA)59条件测试举例(1)2024年5月29日CreativeCommonsLicense(BY-NC-SA)60$
User=osmond$
grep^$User
/etc/passwd$
echo$?$
grep^$User
/etc/passwd>/dev/null\&&echo“$Userisauserin/etc/passwd.”\||echo“$Userisn’tauserin/etc/passwd.”$
Host=centos1$
ping–c1$Host$
echo$?$
ping–c1$Host>/dev/null\&&echo“$Hostisup.”\||echo“$Hostisdown.”条件测试语句语句格式1:test<测试表达式>格式2:
[<测试表达式>]格式3:
[[<测试表达式>]](bash
2.x
版本以上)说明格式1和格式2是等价的,格式3是扩展的test命令在[[]]中可以使用通配符进行模式匹配&&,||,
<,
和>能够正常存在于[[]]中,但不能在
[]中出现[和[[之后的字符必须为空格,]和]]之前的字符必须为空格要对整数进行关系运算也可以使用(())进行测试2024年5月29日CreativeCommonsLicense(BY-NC-SA)61条件测试操作符条件测试表达式中可用的操作符文件测试操作符字符串测试操作符整数二元比较操作符使用逻辑运算符2024年5月29日CreativeCommonsLicense(BY-NC-SA)62文件测试2024年5月29日CreativeCommonsLicense(BY-NC-SA)63[
-ffname
]fname
存在且是普通文件时,返回真(即返回0)[
-L
fname
]fname
存在且是链接文件时,返回真[
-d
fname
]fname
存在且是一个目录时,返回真[
-e
fname
]fname(文件或目录)存在时,返回真[
-s
fname
]fname
存在且大小大于0时,返回真[
-r
fname
]fname(文件或目录)存在且可读时,返回真[
-w
fname
]fname(文件或目录)存在且可写时,返回真[
-x
fname
]fname(文件或目录)存在且可执行时,返回真测试:文件是否存在,文件属性,访问权限等。
更多文件测试符参见test
的在线帮助mantest使用lftp同步yum仓库2024年5月29日CreativeCommonsLicense(BY-NC-SA)64#!/bin/bash##ScriptName:sync_iredmail_yum_repo.shDIST=5ARCH="i386"EXCL_ARCH="x86_64"SRC=/yum/rpms/$DIST/DST=/var/ftp/yum/repos/iredmail/$DIST/$ARCH/[!-e$DST]
&&mkdir-p$DSTexcludes="\"(${EXCL_ARCH})|(repodata)\""cd$DSTlftp-e"setmirror:exclude-regex$excludes&&\mirror--delete--only-newer--verbose&&exit"$SRCcreaterepo.>/dev/null使用reposync同步仓库2024年5月29日CreativeCommonsLicense(BY-NC-SA)65#!/bin/bash##ScriptName:sync_atomic-repo_with_reposync.shARCH="i386"url="/channels/atomic/centos/5"release="atomic-release-1.0-13.el5.art.noarch.rpm"rpm-U$url/$ARCH/RPMS/$releaserpm--import/etc/pki/rpm-gpg/RPM-GPG-KEY.art.txt使用reposync同步仓库之前首先要配置仓库安装atomic-release的RPM包导入其RPM公钥对yum和reposync使用不同的配置文件yum
使用本地仓库配置以加快更新速度/etc/yum.conf和/etc/yum.repos.d/atomic.reporeposync使用运程仓库配置/etc/reposync.conf和/etc/yum/repos.d/atomic.repo使用reposync同步仓库续12024年5月29日CreativeCommonsLicense(BY-NC-SA)66[!-f/etc/reposync.conf]&&(cp/etc/yum.conf/etc/reposync.conf;echo"reposdir=/etc/yum.repos.d">>/etc/yum.conf;echo"reposdir=/etc/yum/repos.d">>/etc/reposync.conf;mkdir/etc/yum/repos.d;mv/etc/yum.repos.d/atomic.repo/etc/yum/repos.d;cat<<__END__>/etc/yum.repos.d/atomic.repo[atomic]name=CentOS/RedHatEnterpriseLinux\$releasever-baseurl=file:///var/ftp/yum/repos/atomic/centos/5/$ARCH/atomicenabled=1priority=1protect=0gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY.art.txtgpgcheck=1__END__)配置对yum和reposync使用不同的配置文件仅当/etc/reposync.conf不存在时执行一次(……)使用reposync同步仓库续22024年5月29日CreativeCommonsLicense(BY-NC-SA)67DST="/var/ftp/yum/repos/atomic/centos/5/$ARCH"[!-e$DST]
&&mkdir-p$DST||cd$DST/usr/bin/yumcleanall/usr/bin/reposync--arch=$ARCH--repoid=atomic\
-d-c/etc/reposync.confcdatomic/usr/bin/createrepo./usr/bin/yumcleanall若本地同步的目标目录不存在创建之,否则进入之使用
reposync
同步仓库的RPM文件-a,--arch:指定架构(i386、x86_64)-r,--repoid:指定要同步的仓库名-d,--delete:删除本地存在而远程已经不存在的文件-c,--config:指定reposync使用的配置文件使用createrepo创建仓库(repodata)字符串测试2024年5月29日CreativeCommonsLicense(BY-NC-SA)68[
-z
string
]如果字符串string长度为0,返回真[
-n
string
]如果字符串string长度不为0,返回真[
str1
=
str2
]两字符串相等(也可使用==)返回真[
str1
!=
str2
]两字符串不等返回真[[
str1
==
str2
]]两字符串相同返回真[[
str1
!=
str2
]]两字符串不相同返回真[[
str1
=~
str2
]]str2是str1的子串返回真[[
str1
>
str2
]]str1大于str2返回真[[
str1
<
str2
]]str1小于str2返回真字符串按从左到右对应字符的ASCII码进行比较字符串的空值检查2024年5月29日CreativeCommonsLicense(BY-NC-SA)69[-z"$name"][!
"$name"][
"X${name}"
=
"X"][-n"$name"
]["$name"][
"X${name}"
!=
"X"]检查空值检查非空值[
"$name"
=
""]["$name"!=
""]整数测试(1)2024年5月29日CreativeCommonsLicense(BY-NC-SA)70[
int1
-eq
int2
]
int1等于
int2返回真[
int1
-ne
int2
]
int1不等于
int2返回真[
int1
-gt
int2
]
int1大于
int2返回真[
int1
-ge
int2
]
int1大于或等于
int2返回真[
int1
-lt
int2
]
int1小于
int2返回真[
int1
-le
int2
]
int1小于或等于
int2返回真[[
int1
-eq
int2
]]
int1等于
int2返回真[[
int1
-ne
int2
]]
int1不等于
int2返回真[[
int1
-gt
int2
]]
int1大于
int2返回真[[
int1
-ge
int2
]]
int1大于或等于
int2返回真[[
int1
-lt
int2
]]
int1小于
int2返回真[[
int1
-le
int2
]]
int1小于或等于
int2返回真操作符两边必须留空格!整数测试(2)2024年5月29日CreativeCommonsLicense(BY-NC-SA)71((int1==int2))
int1等于
int2返回真((int1!=int2))
int1不等于
int2返回真((int1
>
int2))
int1大于
int2返回真((int1
>=int2))
int1大于或等于
int2返回真((int1
<
int2))
int1小于
int2返回真((int1<=int2))
int1小于或等于
int2返回真操作符两边的空格可省略!条件测试举例(2)2024年5月29日CreativeCommonsLicense(BY-NC-SA)72$[$a!=$b];echo$?0$[[$a!=$b]];echo$?0$[$n-gt$m];echo$?1$[[$n>$m]];echo$?1$((n>m));echo$?1$(($n>$m));echo$?1$[[n>m]];echo$?0$a=linux;b=unix$n=5;m=7$[$a!=$b]&&echoT||echoFT$[[$a!=$b]]&&echoT||echoFT$[$n-gt$m]&&echoT||echoFT$[[$n>$m]]&&echoT||echoFF$((n>m))&&echoT||echoFF$(($n>$m))&&echoT||echoFF$[[n>m]]&&echoT||echoFT条件测试举例(3)2024年5月29日CreativeCommonsLicense(BY-NC-SA)73name=Tom;[-z$name];
echo$?name2=Andy;[$name
=$name2
]
;
echo$?name=Tom
[$name
=[Tt]??
]
echo$?name=Tom
[[$name
=[Tt]??
]]
echo$?方括号前后要留空格!x=1;[$x
-eq
1
];
echo$?x=a;[$x
-eq
1
];
echo$?XX[]内不能使用通配符!逻辑测试2024年5月29日CreativeCommonsLicense(BY-NC-SA)74[[
pattern1
&&
pattern2
]]逻辑与
[[
pattern1
||
pattern2
]]逻辑或
[[
!
pattern
]]逻辑非
[
expr1
-aexpr2
]逻辑与,都为真时,结果为真[
expr1
-o
expr2
]逻辑或,有一个为真时,结果为真[
!
expr
]逻辑非((
expr1
&&expr2
))逻辑与((
expr1
||
expr2
))逻辑或((
!
expr
))逻辑非条件测试举例(4)2024年5月29日CreativeCommonsLicense(BY-NC-SA)75[[$x=
1&&$name=To?
]];
echo$?x=1;name=Tom;[$x
-eq
1–a–n$name
];
echo$?注:不能随便添加括号[
(
$x
-eq
1
)–a(
–n$name
)
];
echo$?X(($x==
1&&$name=To?
));
echo$?注:不能在(())中做字符串比较(($x==
1))
&&[[$name=To?
]];
echo$?此处的&&并非逻辑运算符,而是命令聚合(CommandGroup)X[$x
-eq
1-a\(-f"$FN"-o-d"$FN"\)];
echo$?流程控制——分支2024年5月29日76CreativeCommonsLicense(BY-NC-SA)流程控制语句分支
if
条件语句
case
选择语句循环
for
循环语句
while
循环语句
until
循环语句
select
循环与菜单2024年5月29日CreativeCommonsLicense(BY-NC-SA)77循环控制break
语句continue
语句位置参数处理
shift
命令
getopts
命令
分支结构——if语句语法2024年5月29日CreativeCommonsLicense(BY-NC-SA)78ifexpr1#如果expr1
为真(返回值为0)then#那么commands1#执行语句块commands1elif
expr2#若expr1
不真,而expr2
为真then#那么commands2#执行语句块commands2......
#可以有多个elif语句else#else最多只能有一个commands4#执行语句块commands4fi#
if语句必须以单词fi
终止分支结构——if语句说明2024年5月29日CreativeCommonsLicense(BY-NC-SA)79
commands
为可执行语句块,如果为空,需使用shell
提供的空命令“:”,即冒号。该命令不做任何事情,只返回一个退出状态0
if
语句可以嵌套使用
elif
可以有任意多个(0个或多个)
else
最多只能有一个(0个或1个)
if
语句必须以fi
表示结束
exprX
通常为条件测试表达式;也可以是多个命令,以最后一个命令的退出状态为条件值。分支结构——if语句流程1单分支:当“条件成立”时执行相应的操作2024年5月29日CreativeCommonsLicense(BY-NC-SA)80if
条件测试命令命令序列…fi
结束判断条件为真then条件为假分支结构——if语句举例12024年5月29日CreativeCommonsLicense(BY-NC-SA)81#!/bin/bash##filename:areyouok.shecho"AreyouOK?"readanswer#在if的条件判断部分使用扩展的test语句[[...]]#在[[]]中可以使用shell的通配符进行条件匹配if[[$answer==[Yy]*||$answer==[Mm]aybe]]thenecho"Gladtohearit."fi分支结构——if语句流程2双分支:当“条件成立”、“条件不成立”时分别执行不同操作2024年5月29日CreativeCommonsLicense(BY-NC-SA)82if
条件测试命令命令序列1…条件为真then命令序列2…条件为假elsefi
结束判断分支结构——if语句举例22024年5月29日CreativeCommonsLicense(BY-NC-SA)83#!/bin/bash##filename:test-host-up-or-down.sh#if的条件部分可以使用普通的命令进行测试#当命令正确执行($?=0)返回真,否则($?<>0)返回假myhost=centos1.ls-al.meifping-c1-w2$myhost&>/dev/nullthen
echo"$myhostisUP."elseecho"$myhostisDOWN."fi分支结构——if语句举例32024年5月29日CreativeCommonsLicense(BY-NC-SA)84#!/bin/bash##filename:idcheck.sh
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2020版 沪教版 高中音乐 必修1 音乐鉴赏 下篇《第五单元 声情戏韵》大单元整体教学设计2020课标
- 桶装水店员工合同
- 提前终止租赁合同模板
- 2025年南充道路运输货运考试题库
- 2025年阳泉货运从业资格证考试题库答案
- 《壁纸图集》课件
- 2025年烟台b2从业资格证模拟考试题目
- 2025年孝感道路货运从业资格证模拟考试
- 2025年池州考货运资格证考试内容
- 集团资金支付与收款风险控制
- 现代人力资源管理(第三版) 习题及答案
- 加药设备调试报告
- 新苏科版六年级《劳动》上册全一册全部教案(共10课)
- 房地产项目可研测算表-带公式
- 暖通施工方案模板
- 钳工锉削教案公开课一等奖市赛课获奖课件
- 全山东省淄博市2022学年高一数学上学期期末试题含答案
- 公司财务预算工作报告
- 民警工作调动申请书
- 题库(大气科学基础(一)-题库)资料
- 香菇购销合同
评论
0/150
提交评论