SHELL编程[Bash编程手册]===============SHELL编程===============一、Shell语法1.1、变量声明1.2、数组声明和使用1.3、特殊的变量1.4、运算和运算符1.4.1、整数运算符1.5、流程语句1.5.1、if语句1.5.2、case语句1.5.3、select语句1.6、循环语句1.6.1、for语句1.6.2、while语句1.6.3、breake和continue1.6.4、shift二、函数三、shell程序调试四、信号五、bash中常用的命令===============一、Shell语法===============1.1、变量声明变量=值(注意:等号两侧不能有空格)a=”hello”b=9unseta撤销变量areadonlya=2声明静态的变量a=2,不能unsetexport变量名可把变量提升为全局环境变量,可供其他shell程序使用变量应用中要注意:echo“$1=$1;$2=$2“;屏蔽$1,屏蔽$2,直接显示$1,$2,同理*也屏蔽了*的通配符作用${SAT}day,变量要与字符串连在一起时,应该用${}a=`ls-al`反引号,运行里面的命令,并把结果返回给变量aa=$(ls-al)等价于反引号单引号‘’和双引号“”的区别,单引号完全屏蔽$a变量,双引号不屏蔽$a,单引号和双引号都屏蔽*的通配符作用。1.2、数组声明和使用1name[0]=Tom2name[1]=Tomy3name[2]=John4或5name=(TomTomyJohn)例子:1#!/bin/bash2name=(TomTomyJohn)3foriin0124do5echo$i:${name[$i]}6done1.3、特殊的变量$0:脚本名字。此变量包含地址,可以使用basename$0获得脚本名称。$1:第一个参数$2,$3,$4,$5,…一次类推。$#传递到脚本的参数个数$*以一个单字符串显示所有向脚本传递的参数,,以(“$1$2…”)$$脚本运行的ID号$!后台运行的最后一个进程的ID号$@与$*相同,但是使用时加引号,并在引号中返回每个参数。(“$1″”$2″…)$-显示shell使用的当前选项。$?显示最后命令的推出状况。0表示没有错误。例子:1#!/bin/sh2if[$#-ne2];then3echoUsage:$0stringfile;4exit1;5fi6grep$1$2;7if[$?-ne0];then8echoNotFound$1in$2;9exit1;10fi11echoFound$1in$2;上面的例子中使用了$0$1$2$#$?等变量,下面是程序的解释:判断运行参数个数,如果不等于2,显示使用”用法帮助”,其中$0表示就是脚本自己。用grep在$2文件中查找$1字符串。判断前一个命令运行后的返回值(一般成功都会返回0,失败都会返回非0)。如果没有成功显示没找到相关信息,否则显示找到了。其中”表示转义,在”里面还需要显示”号,则需要加上转义符”参数置换的变量1、变量=${参数:-word}:如果设置了参数,则用参数的值置换变量的值,否则用word置换。即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于word的值。[-z${COLUMNS:-}]&&COLUMNS=802、变量=${参数:=word}:如果设置了参数,则用参数的值置换变量的值,否则把变量设置成word,然后再用word替换参数的值。注意,位置参数不能用于这种方式,因为在Shell程序中不能为位置参数赋值。3、变量=${参数:?word}:如果设置了参数,则用参数的值置换变量的值,否则就显示word并从Shell中退出,如果省略了word,则显示标准信息。这种变量要求一定等于某一个参数的值。如果该参数没有设置,就显示一个信息,然后退出,因此这种方式常用于出错指示。4、变量=${参数:+word}:如果设置了参数,则用word置换变量,否则不进行置换。字符串匹配的操作:${PARAMETER#WORD}shell像文件名扩展中那样扩展WORD,并从PARAMETER扩展后的值的开头删除最短的匹配模式(若存在匹配模式的话)。使用‘@’或‘$’即可删除列表中每个参数的模式。${PARAMETER##WORD}导致从开头删除最长的匹配模式而不是最短的匹配模式。${PARAMETER%WORD}shell像文件名扩展中那样扩展WORD,并从PARAMETER扩展后的值末尾删除最短的匹配模式(若存在匹配模式的话)。使用‘@’或‘$’即可删除列表中每个参数的模式。${PARAMETER%%WORD}导致从末尾删除最长的匹配模式而不是最短的匹配模式。${PARAMETER/PATTERN/STRING}shell像文件名扩展中那样扩展PATTERN,并替换PARAMETER扩展后的值中最长的匹配模式(若存在匹配模式的话)。为了在PARAMETER扩展后的值开头匹配模式,可以给PATTERN附上前缀#,如果要在值末尾匹配模式,则附上前缀%。如果STRING为空,则末尾的/可能被忽略,匹配将被删除。使用‘@’或‘$’即可对列表中的每个参数进行模式替换。${PARAMETER//PATTERN/STRING}对所有的匹配(而不只是第一个匹配)执行替换。變數設定方式str沒有設定str為空字串str已設定非為空字串1var=${str-expr}var=exprvar=var=$str2var=${str:-expr}var=exprvar=exprvar=$str3var=${str+expr}var=var=exprvar=expr4var=${str:+expr}var=var=var=expr5var=${str=expr}str=expr6var=exprstr不變7var=str不變8var=$str9var=${str:=expr}str=expr10var=exprstr=expr11var=exprstr不變12var=$str13var=${str?expr}expr輸出至stderrvar=var=str14var=${str:?expr}expr輸出至stderrexpr輸出至stderrvar=str151617[subsir@pinguino~]$x=a1b1c2d218[subsir@pinguino~]$echo${x#*1}19b1c2d220[subsir@pinguino~]$echo${x##*1}21c2d222[subsir@pinguino~]$echo${x%1*}23a1b24[subsir@pinguino~]$echo${x%%1*}25a26[subsir@pinguino~]$echo${x/1/3}27a3b1c2d228[subsir@pinguino~]$echo${x//1/3}29a3b3c2d230[subsir@pinguino~]$echo${x//?1/z3}31z3z3c2d2字符串子集提取:${x:3:5}的值就是“eval”,清单9.shell参数值的子字符串1[subsir@pinguino~]$x=somevalue2[subsir@pinguino~]$echo${x:3:5}3eval字符串长度:您已经知道$#表示参数的数量,而${PARAMETER:OFFSET:LENGTH}扩展适用于单个参数以及$*和$@,因此,可以使用一个类似的结构体${#PARAMETER}来确定单个参数的长度也就不足为奇了。清单10中所示的简单的testlength函数阐明了这一点。自己去尝试使用它吧。清单10.参数长度1[subsir@pinguino~]$testlength(){forpin$@;doecho${#p};done}2[subsir@pinguino~]$testlength1abcdefghi3143571.4、运算和运算符1.4.1、整数运算符整数的算术运算符+-*/%赋值运算符+=-=*=/=%=位运算符&|~^位运算赋值运算符==&=|=~=^=逻辑运算符:&&||!==!===expr命令计算一个表达式的值格式:exprarg例子:计算(2+3)×4的值1、分步计算,即先计算2+3,再对其和乘4s=`expr2+3`expr$s*42、一步完成计算:expr`expr2+3`*4说明:运算符号和参数之间要有空格分开;通配符号(*),在作为乘法运算符时要用、“”、‘’符号修饰关键字let计算表达式的值:#!/bin/bashx=2006letx=$x+1echo$xx=astring.echo$x又出现了新的关键字:let。关于整数变量计算,有如下几种:+-*/%,他们的意思和字面意思相同,在*和/之前必须冠以反斜线,已防被SHELL先行解释。整数运算一般通过let和expr这两个指令来实现,如对变量x加1可以写作:letx=$x+1或者x=`expr$x+1`1.4.2、逻辑运算符对应操作整数字符串相同-eq=不同-ne!=大于-gt小于-lt大于或等于-ge小于或等于-le为空-z不为空-n文件操作逻辑运算符:-dfile----当file是一个目录时,返回True-ffile----当file是一个普通文件时,返回True-rfile----当file是一个只读文件时,返回True-sfile----当file文件长度大于0时,返回True-wfile----当file是一个可写文件时,返回True-x/bin/ls----当/bin/ls是一个可执行文件时,返回True,目录是否可访问-efile----当file存在时,返回True-ofile----当file文件的所有者是当前用户时,返回True-zfile----当file长度为0时,返回True-u-----文件的UID标志被设置-G-----文件的组ID和当前用户相同file1-ntfile2-----文件file1比file2更新file1-otfile2-----文件file1比file2更老逻辑连接符:!expr当expr的值是False时,返回TrueExpr1-aexpr2当expr1,expr2值同为True时,返回TrueExpr1-oexpr2当expr1,expr2的值至少有一个为True时,返回True命令逻辑连接符:[-r$mailfolder]||{echoCannotread$mailfolder;exit1;}使用{}把两个命令括起来,表示一个函数的用法。&&与||或[-f/etc/shadow]&&echoThiscomputerusesshadowpasswors注意:在“[”和“]”符号的左右都留有空格例子:1#!/bin/sh2mailfolder=/var/spool/mail/james3[-r$mailfolder]||{echoCannotread$mailfolder;exit1;}4echo$mailfolderhasmailfrom:5grep^From$mailfolder6其中“^From“表示以From开头的1.5、流程语句1.5.1、if语句1if[逻辑表达式];then2 #commandcode3elif[逻辑表达式];then4 #commandcode5else6 #commandcode7fi如果您为了简洁,想把then和if放在一行,那就要这样写了:if[expression];then。即在then前加一个“;”号。1.5.2、case语句casestring1instr1)commands1;;str2)commands2;;*)commands3;;esac例子:#filelf.gzlf.gz:gzipcompresseddata,deflated,originalfilename,lastmodified:MonAug27