SHELL编程实用教程.docx
《SHELL编程实用教程.docx》由会员分享,可在线阅读,更多相关《SHELL编程实用教程.docx(19页珍藏版)》请在冰豆网上搜索。
SHELL编程实用教程
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和continue
1.6.4、shift
二、函数
三、shell程序调试
四、信号
五、bash中常用的命令
===============一、Shell语法===============
1.1、变量声明
变量=值(注意:
等号两侧不能有空格)
a=”hello”
b=9
unseta撤销变量a
readonlya=2声明静态的变量a=2,不能unset
export变量名可把变量提升为全局环境变量,可供其他shell程序使用
变量应用中要注意:
echo“$1=$1;$2=$2“;屏蔽$1,屏蔽$2,直接显示$1,$2,同理*也屏蔽了*的通配符作用
${SAT}day,变量要与字符串连在一起时,应该用${}
a=`ls-al`反引号,运行里面的命令,并把结果返回给变量a
a=$(ls-al)等价于反引号
单引号‘’和双引号“”的区别,单引号完全屏蔽$a变量,双引号不屏蔽$a,单引号和双引号都屏蔽*的通配符作用。
1.2、数组声明和使用
1name[0]="Tom"
2name[1]="Tomy"
3name[2]="John"
4或
5name=("Tom""Tomy""John")
例子:
1#!
/bin/bash
2name=("Tom""Tomy""John")
3foriin012
4do
5echo$i:
${name[$i]}
6done
1.3、特殊的变量
$0:
脚本名字。
此变量包含地址,可以使用basename$0获得脚本名称。
$1:
第一个参数
$2,$3,$4,$5,…一次类推。
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数,,以(“$1$2…”)
$$脚本运行的ID号
$!
后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
(“$1″”$2″…)
$-显示shell使用的当前选项。
$?
显示最后命令的推出状况。
0表示没有错误。
例子:
1#!
/bin/sh
2if[$#-ne2];then
3echo"Usage:
$0stringfile";
4exit1;
5fi
6grep$1$2;
7if[$?
-ne0];then
8echo"NotFound"$1"in$2";
9exit1;
10fi
11echo"Found"$1"in$2";
上面的例子中使用了$0$1$2$#$?
等变量,下面是程序的解释:
判断运行参数个数,如果不等于2,显示使用”用法帮助”,其中$0表示就是脚本自己。
用grep在$2文件中查找$1字符串。
判断前一个命令运行后的返回值(一般成功都会返回0,失败都会返回非0)。
如果没有成功显示没找到相关信息,否则显示找到了。
其中”表示转义,在”"里面还需要显示”号,则需要加上转义符”
参数置换的变量
1、变量=${参数:
-word}:
如果设置了参数,则用参数的值置换变量的值,否则用word置换。
即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于word的值。
[-z"${COLUMNS:
-}"]&&COLUMNS=80
2、变量=${参数:
=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=$str
2var=${str:
-expr}var=exprvar=exprvar=$str
3var=${str+expr}var=var=exprvar=expr
4var=${str:
+expr}var=var=var=expr
5var=${str=expr}str=expr
6var=exprstr不變
7var=str不變
8var=$str
9var=${str:
=expr}str=expr
10var=exprstr=expr
11var=exprstr不變
12var=$str
13var=${str?
expr}expr輸出至stderrvar=var=str
14var=${str:
?
expr}expr輸出至stderrexpr輸出至stderrvar=str
15
16
17[subsir@pinguino~]$x="a1b1c2d2"
18[subsir@pinguino~]$echo${x#*1}
19b1c2d2
20[subsir@pinguino~]$echo${x##*1}
21c2d2
22[subsir@pinguino~]$echo${x%1*}
23a1b
24[subsir@pinguino~]$echo${x%%1*}
25a
26[subsir@pinguino~]$echo${x/1/3}
27a3b1c2d2
28[subsir@pinguino~]$echo${x//1/3}
29a3b3c2d2
30[subsir@pinguino~]$echo${x//?
1/z3}
31z3z3c2d2
字符串子集提取:
${x:
3:
5}
的值就是“eval”,
清单9.shell参数值的子字符串
1[subsir@pinguino~]$x="somevalue"
2[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~]$testlength1abc"defghi"
31
43
57
1.4、运算和运算符
1.4.1、整数运算符
整数的算术运算符
+-*/%
赋值运算符
+=-=*=/=%=
位运算符
<<>>&|~^
位运算赋值运算符
<<=>>=&=|=~=^=
逻辑运算符:
&&||!
>>=<<=!
===
expr命令计算一个表达式的值
格式:
exprarg
例子:
计算(2+3)×4的值
1、分步计算,即先计算2+3,再对其和乘4
s=`expr2+3`
expr$s*4
2、一步完成计算:
expr`expr2+3`*4
说明:
运算符号和参数之间要有空格分开;
通配符号(*),在作为乘法运算符时要用、“”、‘’符号修饰
关键字let计算表达式的值:
#!
/bin/bash
x=2006
let"x=$x+1"
echo$x
x="astring."
echo$x
又出现了新的关键字:
let。
关于整数变量计算,有如下几种:
"+-*/%",他们的意思和字面意思相同,在*和/之前必须冠以反斜线,已防被SHELL先行解释。
整数运算一般通过let和expr这两个指令来实现,如对变量x加1可以写作:
let"x=$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时,返回True
Expr1-aexpr2当expr1,expr2值同为True时,返回True
Expr1-oexpr2当expr1,expr2的值至少有一个为True时,返回True
命令逻辑连接符:
[-r"$mailfolder"]||{echo"Cannotread$mailfolder";exit1;}
使用{}把两个命令括起来,表示一个函数的用法。
&&与||或
[-f"/etc/shadow"]&&echo"Thiscomputerusesshadowpasswors"
注意:
在“[”和“]”符号的左右都留有空格
例子:
1#!
/bin/sh
2mailfolder=/var/spool/mail/james
3[-r"$mailfolder"]||{echo"Cannotread$mailfolder";exit1;}
4echo"$mailfolderhasmailfrom:
"
5grep"^From"$mailfolder
6其中“^From“表示以From开头的
1.5、流程语句
1.5.1、if语句
1if[逻辑表达式];then
2 #commandcode
3elif[逻辑表达式];then
4 #commandcode
5else
6 #commandcode
7fi
如果您为了简洁,想把then和if放在一行,那就要这样写了:
if[expression];then。
即在then前加一个“;”号。
1.5.2、case语句
casestring1in
str1)commands1;;
str2)commands2;;
*)commands3;;
esac
例子:
#filelf.gz
lf.gz:
gzipcompresseddata,deflated,originalfilename,
lastmodified:
MonAug2723:
09:
182001,os:
Unix
脚本:
1#!
/bin/sh
2ftype=`file"$1"`
3case"$ftype"in
4"$1:
Ziparchive"*)unzip"$1";;
5"$1:
gzipcompressed"*)gunzip"$1";;
6"$1:
bzip2compressed"*)bunzip2"$1";;
7*)#*通配符代表其他
8error"File$1cannotbeuncompressedwithsmartzip";;
9esac
例子:
1#!
/bin/bash
2echo"Hitakey,thenhitreturn."
3readKeypress
4
5case"$Keypress"in
6[a-z])echo"Lowercaseletter";;
7[A-Z])echo"Uppercaseletter";;
8[0-9])echo"Digit";;
9*)echo"Punctuation,whitespace,orother";;
10esac
11exit0
1.5.3、select语句
尤其擅长于交互式使用。
用户可以从一组不同的值中进行选择。
selectvarin…;do
break
done
例子:
1#!
/bin/sh
2echo"WhatisyourfavouriteOS?
"
3selectvarin"Linux""GnuHurd""FreeBSD""Other";do
4 break
5done
6echo"Youhaveselected$var"
#下面是该脚本运行的结果:
WhatisyourfavouriteOS?
1)Linux
2)GnuHurd
3)FreeBSD
4)Other
#?
1
YouhaveselectedLinux
1.6、循环语句
1.6.1、for语句
forvarin数组列表;do
#commandbolock
done
例子1:
1#!
/bin/bash
2forvarinABC;do
3 echo"varis$var"
4done
例子2:
1#!
/bin/sh
2#列出RPM的数目
3#用法:
showrpmrpmfile1rpmfile2...
4#EXAMPLE:
showrpm/cdrom/RedHat/RPMS/*.rpm
5forrpmpackagein$*;do
6 if[-r"$rpmpackage"];then
7 echo"==$rpmpackage=="
8 rpm-qi-p$rpmpackage
9 else
10 echo"ERROR:
cannotreadfile$rpmpackage"
11 fi
12done
例子3:
1forvar1in"$@"
2do
3#statements
4done
例2和例3的$*和“$@”是相同的
1.6.2、while 语句
while[express];do
#command
Done
例子1:
1count=1
2while[-n"$*"]
3do
4echo"thisisaparameternumber$count$1"
5shift
6count='expr$count+1'
7done
例子2:
1while[-n"$1"];do
2case$1in
3-h)help;shift1;;#functionhelpiscalled
4#执行help函数,shift1表示,移除第一个变量$1,则第二个变为:
$1
5 -f)opt_f=1;shift1;;#variableopt_fisset
6 -l)opt_l=$2;shift2;;#-ltakesanargument->shiftby2
7 --)shift;break;;#endofoptions
8 -*)echo"error:
nosuchoption$1.-hforhelp";exit1;;
9 *)break;;
10esac
11done
就像平常执行命令一样,当有参数-h时,则执行相应的动作
1.6.3、breake和continue
关键字”break”用来跳出循环。
而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。
1.6.4、shift
shift将存放在位置变量中的命令行参数,依次向左传递.例如
位置变量当前值为:
$1=file1$2=file2$3=file3
执行一次shift命令后,位置变量的值为:
$1=file2$2=file3
还可以在shift命令中指定位置变量转移的次数,如:
shiftn
例子:
1while["$1"]
2do
3if["$1"="-i"]then
4infile=”$2″
5shift2
6elseif["$1"="-o"]then
7outfile=”$2″
8shift2
9else
10echo“Program$0doesnotrecognizeoption$1″
11fi
12done
二、函数
脚本b2d将二进制数(比如1101)转换为相应的十进制数。
这也是一个用expr命令进行数学运算的例子:
1#!
/bin/sh
2#vim:
setsw=4ts=4et:
3help()
4{
5 cat6USAGE:
b2h[-h]binarynum
7OPTIONS:
-hhelptext
8EXAMPLE:
b2h111010
9willreturn58
10HELP
11 exit0
12}
13
14
15error()
16{ #printanerrorandexit
17 echo"$1"
18 exit1
19}
20
21lastchar()
22{ #returnthelastcharacterofastringin$rval
23 if[-z"$1"];then
24 #emptystring
25 rval=""
26 return
27 fi
28 #wcputssomespacebehindtheoutputthisiswhyweneedsed:
29 numofchar=`echo-n"$1"wc-csed''s///g''`
30 #nowcutoutthelastchar
31 rval=`echo-n"$1"cut-b$numofchar`
32}
33
34chop()
35{ #removethelastcharacterinstringandreturnitin$rval
36 if[-z"$1"];then