循序渐进UNIX--UNIX Shell 程序设计

UNIX Shell? 程序设计

http://91mail.51.net提供??需要完整的pdf文档请到http://91mail.51.net下载
??? UNIX? Shell概述
??? Shell启动及其命令
??? Shell命令的集成
??? Shell 变量
??? Shell的控制结构
??? Shell的运行环境
???
?第一节UNIX Shell概述
*? ?什么是 Shell
*? ?Shell的双重特性
*? ?Shell程序语言的特点
*? ?Shell的版本
*? ?Shell版本的选择
什么是 Shell

?? Shell就是UNIX提供用户的使用界面 。
Shell处在内核与外层应用程序之间,起着
协调用户与系统的一致性、在用户与系统
之间进行交互的作用,即 Shell为用户提供
了输入命令和参数并可得到命令执行结果
的环境。
Shell的双重特性
?F? 命令解释程序(命令解释器)
??????? Shell解释用户输入的命令行,提交系统内核
处理,并将结果返回给用户;
??? Shell与UNIX命令一样都是实用程序,但有区
别。一旦用户注册到系统后, Shell 就被系统装
入内存,并一直运行到用户退出系统之止;而一
般命令仅当被调用时,才由系统装入内存执行。
?F? 程序设计语言
??? Shell本身也是一种可编程的程序设计语言。
6.1.1? Shell的特点和主要版本?
???? Shell允许通过编程来完成复杂的功能处理,
但其作为语言与高级语言比较具有不同的特点:
? Shell是解释性的,多数高级语言是编译性的;
?· Shell语言与高级语言处理的对象不同;
?¸ Shell与系统有密切的关系;
?¹ Shell易编写、调试、灵活性较强,但速度低;
?º Shell作为命令级语言,命令组合功能很强。
Shell的版本?
Shell版本的选择
选择Shell版本应考虑的因素:
?? Bourne Shell在任何一个UNIX系统平台上都存在,因此又成为标准Shell;
?·? Bourne Shell家族有更丰富的程序语言,而 C Shell家族有简单的程序接口;
?¸? Shell各类变种功能越来越强大,但学习和使用也越难,因此可依据使用者编程经验来选择;
?¹ Shell编程的脚本是个人使用还是公用,即要
考虑移植性问题。

6.1.2? shell程序示例
6.1.3 shell脚本的建立和执行
第2节 Shell变量
*???? Shell变量
*???? 用户自定义变量
*???? 位置变量
*???? 预定义的特殊变量
*???? 环境变量
*???? 变量替换

?F?? Shell实际上是基于字符串的程序设计语言,
也具有变量。变量的名字必须以字母或下划线
开头,可以包括字母、数字和下划线。
?F?? Shell变量能够而且只能存储正文字符串,
即它只有一种类型的变量——串变量。
?F?? 从赋值的形式上看,则可以分成四种类型
的变量或变量形式。
F? shell有两种变量:环境变量和临时变量。

环境变量:永久变量
???????????????????? 用户自定义变量
??????????????????????? 位置参数


?6.2.1? 用户定义的变量
F?语法格式:变量名=字符串
F?在程序中使用变量时,要在变量名前加一个符号“$”
?F赋值号“=”两边不允许有空白符;
??? nodehost="beijing.UUCP ”
??? path=/bin:/usr/bin:/etc/bin
??? count=10
?F 允许多个赋值操作,按从右到左的顺序进行;
??? # A=$B? B=abc? C="OK"
??? # echo $A $B $C
?????????? abc abc OK
?

?F 当引用一个未设置的变量时,其隐含值为空;
??? # echo? "$mail is path of mailbox”
????????? is path of mailbox
F 如果用双引号“”将值括起来,则括起来的
字符串允许出现空格、制表符和换行符的特殊字
符,而且允许有变量替换。?
?? 例1:# MAIL=/var/mail/fk
???????????? # var="$MAIL is a path of mailbox"
???????????? # echo $var
???????? /var/mail/fk is a path of mailbox
??

例2:# str="This is /n a book"
???????????? # echo $str
???????????? This is
?????????????? a book


?F 如果用单引号‘’将值括起来,则括起来的字符串允许出现空格、制表符和换行符的特殊字符,但不允许有变量替换。?? 例1? # BOOK="English book"
?????????? # MSG='$BOOK'
?????????? # echo $MSG
??????????? $BOOK???
?? 例2?? # msg=' Today is /t Sunday'
?????????? # echo $msg
?????????? Today is???????? Sunday

?F 引用变量的值时,可以用花括号{}将变量名称括起来,使变量名称与它的后续字符分隔开,如果紧跟在变量名称后面的字符是字母、数字或下划线时,必须要使用花括号。?
?? 例: # str='This is a string'
??# echo "${str}ent test of variables"
??This is a stringent test of variables
??# echo "$strent test of variables"
??test of variables
6.2.2输入输出命令
1.read命令
??????? 可以利用read命令由标准输入读取数据,然后赋给指定的变量
格式:read? 变量1 [变量2…]
例如:read name
??????????? read a b c
?

F 若变量数少于数据个数
例如执行 read n1 n2
时,用户输入:
First Second Third <回车〉>
则将“First”赋给n1,将“Second Third”赋给n2
F若变量数多于数据个数
例如,read? n1? n2? n3,用户输入:1?? 2 <回车>
则 n1取值1, n2取值2,n3为空串。

2.echo命令
??????? echo命令将其后的参数在标准输出上输出。
?echo参数中可以有一些特殊字符? p139
例:echo “Enter the file name->/c”
2.3? 位置参数
?????? 位置变量顾名思义是与位置有关的变量,这
是一种特殊的变量。命令行的Shell过程名本身被
指定为位置变量$0,依次参数为$1 …. $9 。
?例:ls???? /?? /bin? /etc? /usr/bin? /dev?? …
???????????? ×???? ×?????? ×?????? ×???????? ×???????????? ×
?? $0?? $1?? $2??? $3???? $4???????? $5??? …
???? 例:# cat? finduser
?????????????? who | grep $1
??????????? # finduser fke

例6-5 位置参数的使用
$ cat m1.c
? main( )
?{
?? printf(“bebin/n”)
?}
$cat m2.c
? #include
? main( )
? {
? Printf(“ok/n”)
? Printf(“end/n”)
? }

$cat ex5
#ex5:shell sript to combine files and count
#lines
????? cat $1 $2 $3 $4 $5 | wc –l
#end
$ ex5 m1.c m2.c
?10

F在shell程序中可以利用set命令为位置参数赋值。例如:
??? set m1.c m2.c m3.c
就把字符串m1.c赋给$1,字符串m2.c赋给$2,字符串m3.c赋给$3。但$0不能用set赋值
例6-6? 用set 设置位置参数值
?$ cat ex6
?? set m1.c m2.c
?? cat $1 $2 $3 $4 $5 | wc-l
$ ex6
10
6.2.5? 预定义的特殊变量
?? 在Shell中有一组特殊的变量,其变量名和变量值只有Shell本身才可以设置。
?F? $#? — 记录传递给Shell的自变量个数;
? 例1: # myprog? a? b? c????????? 则? $#的值为3
? 例2: if? test $#? -lt? 2
?????????? then
???? echo? “two or more args required”
???? exit ?
??????? fi?

例6-2
$ cat ex2
?if test $# = 0
?? then ls
else
??? for i
????? do
????????? ls –l $i
?????? done
fi
2.5? 预定义的特殊变量(续1)
F $? —? 取最近一次命令执行后的退出状态(返???????? 回码) :执行成功返回码为0, 执行失???????? 败返回码为1;
?例:# test? -r? my_file?? (假设my_file文件不可读)????
?? # echo?? $?
??????????? 1
F $$?? —? 当前进程的进程号 ;p142
F $! —? 取最后一个在后台运行的(使用“&”)
????????? 进程的进程号 ;?????????? ??
2.5? 预定义的特殊变量(续2)
?F? $-? —? Shell的标志位,既在Shell启动时使用 的选项,或用set命令方式所提供的选项。
?F? $*? —? 匹配所有位置变量 ; ??
????????? $*??? 匹配?? $1? $2? $3? …
??? ·??? “$*”? 匹配? “$1? $2? $3? …”
?F? $@? —? 匹配所有位置变量 ; ??
????????? $@? 匹配??? $1? $2? $3? …
??? ·??? “$@” 匹配? “$1” “ $2” “$3 ” …
6.2.6? 环境变量
?? Shell执行环境由一系列环境变量组成,这些变
量是由Shell维护和管理的。所有这些变量都可被
用户重新设置,变量名由大写字母或数字组成。
?CDPATH:执行cd命令时使用的搜索路径;
?HOME :用户的home目录;
?IFS?????? :内部的域分隔符,一般为空格符、制表符??????????
???????????????????? 或换行符;
?MAIL?? :?? 指定特定文件(信箱)的路径,供邮件系统用;
?PATH? :寻找命令或可执行文件的搜索路径;
?PS1?????? :?? 主命令提示符,默认为“$ ”或“#”;
?PS2?????? :?? 从命令提示符,默认为“> ”;
?TERM? : 使用的终端类型。p144
6.2.7 export语句与环境设置
????????????????? 局部变量和全局变量
局部变量在某一局部特定环境下使用的变量 。
?F? 注册Shell在接受到用户输入的命令(非内部
命令)后,通常派生出一个子Shell,由此子Shell
负责解释执行该命令。
? F 子Shell有自己的运行环境和变量,这些变量
仅在子Shell的范围内的特定环境下才能使用。
?

F 子Shell不能存取由父Shell设置的局部变量,
也不能改变父Shell的变量值。
例1:? # cat vartest1
??????? echo :$x:
??? ??? # x=100
???? # vartest1
???? ::
? 例2:? # cat vartest2
??? x=60
??? echo :$x:
??? # x=10
??? # vartest2
??? :60:
??? # echo $x
??? 10
全局变量
? ? 全局变量是一种特殊的变量,可以被任何运行
的子Shell来引用。全局变量通过export命令来定
义,格式如下:
??export? variables
其中 variables 是要变成全局变量的变量表名。
?F? 一旦变量被定义为全局变量,则对于以后的
所有子Shell来说这些都是全局变量;
?F? 子Shell中无法改变全局变量的值;
?F? 若在子Shell中改变全局变量的值,实际是对
全局变量的副本进行更改,不影响全局变量值;
?F? 子Shell中局部变量的使用优先于全局变量。

? 例:? # export g_var
??# g _var="GLOBAL"
??# cat test_var
??export g_var l_var
??g_var="sub_shell:g_var"
??l_var="sub_shell:l_var"
??echo $g_var $l_var
??# test_var
??sub_shell:g_var sub_shell:l_var
??# echo $g_var? :$l_var:
??GLOBAL ::
??# ?
局部变量和全局变量作用域
? 任何没有用export命令定义过的变量是局部变
量,子Shell不能存取父Shell的局部变量;
?· 子Shell中可以存取和修改父Shell的全局变量,
但这种修改对于父Shell全局变量没有任何影响;
?¸ 在子Shell中用export命令定义的全局变量和对
此变量的修改对父Shell变量没有影响;
?¹ 全局变量保持它的全局性,不仅能直接传递给
它的子Shell,而且子Shell还能将它传递给子Shell
的子Shell;
?º 在对变量赋值之前和之后的任何时候可以将该
变量转换成全局变量。

1export语句
???? p144
2. .profile文件?????? p145
??? 如果修改了.profile文件需重置环境,即重新执行.profile文件。$ $HOME/.profile
3.环境变量的设置和显示
4.set 命令?????????????????????????


例6-8
$ cat ex8
? set –x
?? a=1;b=5
? echo”current shell flags $-”
?? echo $a $b
? set +x
? echo”current shell flags $-”
? set –v
? A=2;B=8
?echo”current shell flags $-”
?echo $A $B
?set +V
?echo”current shell flags $-”

$ ex8
?a=1
b=5
+ echo current shell flags x
Current shell flags x
+ echo 1 5
1 5
+ set +x
Current shell flags
A=2; B=8
Echo “current shell flags $-”
Current shell flags v
Echo $A $B
2 8
Set +v
Current shell flags


6.3 shell中的特殊字符
3.1??? UNIX元字符(通配符)的定义
?*??? 匹配任何字符串,包括空字符串;
??? 匹配任何单个字符;
? [ … , - , ! ] 按照范围“-”、列表“...”或不匹配
?????????????????????????? “!”等形式匹配指定的字符;
?/???? 转意符,使元字符失去其特殊的含义。??
?例:[a-d,x,y] 匹配字符a、b、c、d、x、y;
????  ?? z*??? 匹配以字符z开始的任何字符串;
?????? x?y?? 匹配以x开始、以y结束、中间为任何?单个字?? ??????? 符的字符串;
????? [!Z] 匹配不为Z的单个字符。?
6.3.1? 元字符(续)
例:[a-f]* 匹配字符a到字符f开头的文件名;
???abc?? d2?? e3.c? f.dat  
 ?  ?*z ?匹配以字符z结尾的任何字符串;
???win.z?? core.zz?? a-c_5z
??rc?.d?匹配以rc开始、以.d结束、中间为任
???何单个字符的文件名;
???rc0.d?? rc2.d? rcS.d
?????? *[!o]? 匹配不以o结尾的文件名;
????
6.3.2? 消除特殊字符的含义可用转义符、单引号和双引号。
?F 双引号 (“”)的引用
?双引号能消除被括在双引号中大部分特殊字符的含义,但不能消除 $ 、` 、"? 、/? 四个字符的其特殊含义:?
?例: vdate=“`date` is system maintenance day !”
F 单引号 (‘’)的引用
?? 消除被括在单引号中的所有特殊字符的含义。
?例:# echo ‘$count=’$count
?F? 转义符( /) 的引用
? 消除紧跟在转义符后面的单个字符的特殊含义 。
??例?? #count=`expr count /* 10`
?
?F 特殊字符串引用的例外
???? 引用双引号、单引号和转意符都不能消除对
echo命令有特殊功能的控制字串(逃逸字符)的
特殊含义。这些控制字串是:
?/b?Backspace
?/c?显示后不换行
?/f?在终端上屏幕的开始处显示
?/n?换行
?/r?回车
?/t?制表符
?/v?垂直制表符
?/?反斜框
6.3.3? 输入、输出重定向符
F? 使用标准改向符进行重定向(改向)?
??? ? ??< ??>???????????? 输出改向
????????? >>????? 追加输出改向?
?F 使用标准文件描述字进行重定向(改向)?
?? ??? 在UNIX系统中,使用了文件描述字来定义输入、输出的标准文件,其中:
? 0:标准输入??? 1:标准输出??? 2:标准错误输出
6.3.3? 输入、输出重定向(续1)
?F 标准输入的改向(< 、 <<)
?????? command? < file
??? ·?? command? << End Of? Marker
??????? >
???????? :
??????? :
??????? > End Of Marker
? 例1:sort ? 例2:cat << !eof
??? > Hellow !
???????????? > ok !!
??? >!eof
3.3? 输入、输出重定向(续2)
?F 标准输出的改向(>、 >>)
???? command? > file
?? ·? command? >> file
?例1:date? >? myfile
??? 例2:ls -l? >>? myfile
??? 例3:cat? file*? >? myfile ?
??? 例4:ps -ef? |? grep? ftp >? myfile
6.3.3? 输入、输出重定向 ( 续3 )
?? F 标准错误输出的改向(>、 >>)
?????? command? 2 >file
???? ·? command? 2 >>file
? 例1:将错误输出改向到err_file文件。
??myprog? 2 > err_file
???? 例2:将标准输出和错误输出改向out文件。
??myprog >out? 2 >>out?? (两种方法等价)
??myprog >out? 2 >>&1? (改向处理从左至右)
?? 例3:错误输出被显示,标准输出改向out文件。????? ?myprog? 2 >&1? >> out
6.3.4? 注释、管道和后台命令
F注释??? shell程序中以#开头的正文行表示注释
F? 管道的概念
??? 管道:是一个命令的标准输出与另一个命令
的标准输入之间的连接,不经过任何中间文件;
??? 管道线:是由管道操作符分隔的一个命令序
列,最简单的管道线是一个简单命令;
????? 管道操作符:用符号“|”表示。
??例: who | wc -l
???? ps -ef | grep ftp
???? ls –l
F后台命令? 在一条命令的最后键入&
管道(续1)
?F? 命令表的概念
?命令表:一串管道线(命令)构成了一个命令表,最简单的命令表是一个管道线(即一个简单命令)。
3.5 管道线(命令)分隔符(命令执行操作符)
??????? 分隔命令表元素,确定管道线执行的条件,含义
如下:
? ;或 换行符? :表示按顺序执行管道线;
&& :? 表示根据条件(true),执行其后面的管道线;
? | |?? :?? 表示根据条件(false),执行其后面的管道线;
?? &? :?? 表示前面的管道线在后台(异步)执行。
管道(续2)
?例1:四个管道线构成一个命令表
????? ls? -l? /bin? /usr/bin
????? who | wc -l
????? a | b | c | d
????? ps?
?例2:与例1等价
????? ls -l /bin /usr/bin ;who | wc -l ;a | b | c | d;ps
?例3:sys_account &
?例4:查询指定的文件是否存在,给出相应信息
???? test? -f? $1 &&? echo “$1 exists”
???? test? -f? $1? | |? echo “$1 not exists”
6.3.6 命令组合(成组命令)
?????? 命令组合有两种形式:
? F? { 命令表 }
????? 由当前Shell来执行命令表。
?? 例:{?? cd? mydoc ;rm junk;}
???
? F? ( 命令表 )
???? 当前Shell派生一个子Shell进程来执行命令表。
?? 例:(? cd? mydoc ;rm junk;)
?

6.4 参数置换变量
用命令的执行结果来替换这个字符串本身
注意? 反撇号与单引号的区别。
? 例1:# now=‘date’??????? ï? 单引号
?? # echo $now
?? date
?? # now=`date`????????????? ï? 单撇号
?? # echo $now
?? 1999年 12月 8日 星期三 19时 51分 56秒 CST
? 例2: # count=10
???????????? # count=`expr $count + 1`
???????????? # echo $count
???????????? 11

??? 参数置换变量是另一种为变量赋值的方式,其一般形式为:
????????? 变量2 = ${变量1 op 字符串}
??? Shell在遇到未设置的变量时,将其值作为空
串处理。而在实际应用中,对于未设置的变量,
用户可以根据需要采用不同的处理方式,这可通
过变量替换来实现。
??? 变量替换提供了三种功能:
?????? 允许替换未设置变量的隐含值;
?·?? 允许对未设置变量赋值;
?¸?? 在访问未设置变量时,提示出错信息。
6.2.6? 变量的替换(续1)
6.2.6? 变量的替换(续2)
? 例1:${var:-word}?(假设$ PARM未设置)
?# echo? " The value of? PARM is ${PARM:-undefined}"
?The value of PARM is undefined
?# echo $PARM
???? 0???????????? [注意]? 此处的“ 0” 表示空字符
?$
? 例2:${var:-word}?(假设$ PARM未设置)
? # arg=${PARM:-“not defined”}????? [注意] 双引号
? # echo ' $arg : '$arg
? $arg : not defined??
第5节 Shell的控制结构
*???? if 结构
*???? 条件和 test 命令
*???? case 结构
*???? while 结构
*???? until 结构
*???? for 结构
*???? 循环体中的其它命令
5.1? if 结构
?F? if 的简单结构
?格式??? if 测试条件
??????? then
???command2
???command3
???…
?????? fi
5.1? if 结构(续1)
?F? if 的完整结构
?格式??? if? 测试条件
??????? then
???command2
???command3
???…
??????? else
???command4
???command5
???…
?????? fi
5.1? if 结构(续2)
?F? if 的连用结构
?格式1??? if? 测试条件
???????? then
??????????? commands
???????? else
??????????? if command2
??????????? then
??? commands
????????????????? :
?????? :
??????????? fi
??????? fi
5.1? if 结构(续3)
?F? if 的连用结构
?格式2??? if? 测试条件
???????? then
??????????? commands
???????? elif command2
???????? then
??????????? commands
????????????????? :
????????????????????????? :
??????????? commands
???????? else
??????????? commands
???????? fi

•?条件测试可以利用一般命令执行成功与否来判断。p161

5.2? 条件与 test 命令
?F? 简单条件
??? 在高级语言中判断条件依赖于运算的结果,而
Shell语言依赖条件是命令执行的“出口状态”。
??? Shell命令的“出口状态”($?):
?????????? 成功:0? 、 true
?????????? 失败:x? 、 false??? (x 为非0数值)
例:判断指定目录是否存在, 并显示相应信息。 #? cat? checkdir
?test -d $1 && echo “$1 is a dictory”&& exit 0
?echo “$1 is not a dictroy”
?exit 1
5.2? 条件与 test 命令
?F? test 命令
????? test 命令可用于对字符串、整数及文件进行各
类测试。其命令格式如下:
??test? expression?
?? 或?? [? expression? ]???????? 注意? [ ] 中的空格)
? ???? expression 是测试的条件,计算结果:
?????????? 为真,则返回“零”出口状态,
?????????? 为假,否则返回“非零” 出口状态。
?例:判断当前上机用户人数是否多于10 ?
???????????? #? test "`who | wc -l ` " -gt 10
?????????? # echo $?
5.2? 条件与 test 命令
?F? test 中常用的文件测试表达式?
5.2? 条件与 test 命令
?例1:检查指定的文件是否存在并且可读
?test? -r? /usr/fk/message
?例2:检查指定的文件是否为目录
? test? -d? /usr/src/local/sendmail
?例3:检查指定的出错文件是否为空,如不空
??则列出该文件的内容。
? test? -s? $errfile? &&? cat? $errfile
5.2? 条件与 test 命令
?F? test 字符串测试表达式? ?
5.2? 条件与 test 命令
?例1:两个字符串进行比较
?# user=smith
?# test "$user"?? =? smith
?# echo $?
?0
? 例2:查找指定的文件或目录
???? # cat search
????? test "$1" || { echo "err: no parameter" ;? /
?????????????????????? exit 1; }
???? find . -name "$1" -print
5.2? 条件与 test 命令
?例2:带有空格的字符串比较
?# month="January? "????????????
?# test "$month"? =? January
?# echo $?
?1
?# test $month? =? January
?# echo $?
?0
?区别:Shell在处理变量时,遇到有双引号将保留其内容,而省略双引号时,将滤去空格。
5.2? 条件与 test 命令
?例3:带有空格的字符串比较
?# a="testing string"
?# test "$a"? =? "testing string"
?# echo $?
?0
?# test $a? =? "testing string"
?test: unknown operator string

??? Shell处理变量 $a 时,将其进行变量替换,然
后将结果(testing string)传递给test,而test将string
作为操作符来处理,因此出错。
5.2? 条件与 test 命令
?例4:带有空串(或未设置的字符串比较)
?# name= " "
?# test "$name"? =? smith
?# echo $?
?1
?# test $name? =? smith
?test: argument expected
??? Shell处理变量"$name"时,双引号将其括起
的内容作为一个“位置持有者”来保留,并把该
值传递给test,保证处理的正常执行。
5.2 条件与 test 命令
?例4:带有空串的字符串比较
?# blanks="???? "
?# test $blanks
?# echo $?
?1
?# test "$blanks"
?# echo $?
?0
???? Shell处理变量$blanks时,将空格滤去,使其
变为空串传递给test;而双引号保留 “位置持有
者”的位置,其值为一个空格(空白符),传递
给test。
5.2? 条件与 test 命令
?例4:带有算符的字符串比较
?# symvar="="
?# test -z "$symvar"
?test: argument expected
?????? 出错的原因是“=”运算符比“-z”运算符的优先级
要高,因此,test 命令期望在等号之后要有一个自变量。
为避免上述问题的发生,可用下面命令形式替换:
?# test x"$symvar" =? x
?# echo $?
?1
5.2? 条件与 test 命令
?F? test命令可用于整数比较
?? 首先要搞清楚整数比较的两个概念:
???? Shell并不区分放在Shell变量中的值的类型,
就变量本身而言,它存放的仅仅是一组字符串,
既Shell只有一种类型的变量——串变量。
??? · 当使用整数比较操作符时,是test命令来解
释存放在变量中的整数值,而不是Shell。 ?
5.2? 条件与 test 命令(续12)
?F? test 整数测试表达式?? ?
5.2? 条件与 test 命令(续13)
?例:
?# x1= " 005 "
?# x2= " 10"
?# test " $x1 " = 5????????????? ï? 按串方式比较
?# echo $?
?1
?# test " $x1 " -eq 5?????????? ï? 按数值方式比较
?# echo $?
?0
?# test " $x2 "? -eq 10
?# echo $?
?0???? ?
6.5.2? 条件与 test 命令
?F? 表达式的逻辑运算
??? 逻辑运算符包括:
?!?? —?? 逻辑非单目运算符,可放置在任何其它
test表达式之前,求得表达式运算结果的非值。
? -a?? —?? 逻辑与运算符,执行两个表达式的逻辑
与运算,并且仅当两者都为真时,才返回真值。
? -o? —??? 逻辑或运算符,执行两个表达式的逻辑
或运算,并仅当两者之一为真时,就返回真值。
5.2 条件与 test 命令
?F? 逻辑运算符的优先级
??? 逻辑运算符优先级(由高到低) 的排列顺序
?如下:
???? ( )? Ý??? !??? Ý??? -a???? Ý???? -o
?·?? 逻辑运算符优先级要比字符串操作符、数
字比较操作符、文件操作符的优先级低。
6.5.2? 条件与 test 命令
?F? 表达式的逻辑组合?
6.5.2? 条件与 test 命令
?例1:当指定的文件不可读时为真。
?test ! -r /usr/fk/message
?例2:当指定的文件均存在,且message为可读、
???? $mailfile 指定的文件为普通文件时,返回真。
?test? -r /usr/fk/message? -a? -f? "$mailfile "
?例3:当变量值大于等于0并且小于10时为真。
?test? "$count "? -ge 0? -a? "$count "? -lt 10 ??
?例4:
??? test? /( “$a” -eq 0? -o? "$b"? -gt 5 /)?? -a? "$c"? -le 8
6.5.3? case 结构
??格式???? case value in
?????? pattern1)??? command11
?????????? …
?????????????????????????? command1n;;
??? ???? pattern2)??? command21
?????????? …
?????????????????????????? command2n;;
??????????? …???????????????? …
?? ??? ????? patternn)??? commandn1
?????????? …
?????????????????????????? commandnn;;
????????? esac?????
5.4? while 结构
??格式
???? while command
???? do
???command
???????? …
???command
????? done
5.5 until 结构
??格式
???? until command
???? do
???command
???????? …
???command
????? done
5.6? for 结构
??格式
???? for? variable in arg1 arg2 … argn
???? do
???command
???????? …
???command
????? done
5.7? break命令和continue命令
?F? break 命令
?? break是Shell的内部命令,用于在循环体中根
据命令运行的返回条件,直接终止循环体内命令
的执行。
?? 当执行break命令时,控制流从循环体中转移
到done之后的第一条命令上。
5.7 break命令和continue命令
?F? continue 命令
?? continue是Shell的内部命令,用于在循环体中
根据命令运行的返回条件,直接进入下一次循环
命令的执行。
?? 当执行continue命令时,控制流直接转到本循
环体中第一条命令上。
5.10? 函数的定义和使用
?? 函数格式
??FunctionName( ){
?????? command
????? :
????? :
???command
???? }?
5.10? 函数的定义和使用
?例:? ### The test codes for function definition
??GetYesOrNo() {
??? while echo “$*(Y/N)? /c” > &2
??????????? do
?????? read reply RestData
?????? case? “$reply”in
??????????? [yY] ) ?return 0 ;;
??????????? [nN] )??? return 1 ;;
???*???? )??? echo “Please enter Y or N !”>&2 ;;
?????? esac
???? done?
?执行? # GetYesOrNo “Do you wish to continue” || exit
?显示? Do you wish to continue(Y/ N)?
第七章 Shell的运行环境
*???? 局部变量
*???? Shell程序的应用
*???? 全局变量
*???? 局部变量和全局变量作用域
*???? 程序调试?
7.4? 程序调试
??????? Shell提供了多种工具以便在调试Shell程序时
使用,这些工具允许观察一个Shell程序的执行。
?????? 常用的测试方式有:
????????? Shell程序的详细跟踪;
????????????? Shell程序的跟踪执行;
?
7.4? 程序调试(续1)
?F? Shell程序的详细跟踪
??? Shell提供的详细跟踪特性允许用户观察一个
Shell程序的读入和执行,如果在读入命令行时发
现语法错误,则终止程序的执行。命令行被读入
后,Shell按读入时的形式在标准错误输出中显示
该命令行,然后执行命令行。详细跟踪Shell程序
的执行有两种方式:
?? 整个程序的详细跟踪和局部程序的详细跟踪。

7.4? 程序调试(续2)
?? 整个程序的跟踪执行
?格式????
??sh? -v? shprog
?? 用来实现对整个文件的脚本进行跟踪。
?·? 局部程序的跟踪执行
?格式????
??set?? -v???? ——? 设置跟踪标志
??set? +v???? ——? 关闭跟踪标志
?? 用来实现对文件中的部分脚本进行跟踪。 ?
7.4? 程序调试(续3)
?例:? # cat traced
??? date
??? echo $PATH | wc -c
??? # traced
??? 1998年 11月 05日 星期四 17时 29分 59秒 CST
??? ??? 45
??? # sh -v traced
??? date
??? 1998年 11月 05日 星期四 17时 30分 08秒 CST
??? echo $PATH | wc -c
???? ?? 45????????????????????
7.4? 程序调试(续4)
?F? Shell程序的跟踪执行
??? Shell的跟踪执行功能允许用户观察一个Shell
程序的执行,它使命令行在执行前完成所有替换
之后,在标准错误输出中显示每一个被替换后的
命令行,并且在行前加上前缀符号“+”(但变
量赋值语句不加“+”符号),然后执行命令。
?? 同详细跟踪一样,对Shell程序的跟踪执行也
有两种方式:
?? 整个程序的跟踪执行和局部程序的跟踪执行。
7.4? 程序调试(续5)
?? 整个程序的跟踪执行
?格式????
??sh? -x? shprog
? 用来实现对整个文件脚本的跟踪执行。
?·? 局部程序的跟踪执行
?格式????
??set?? -x???? ——? 设置跟踪标志
??set? +x???? ——? 关闭跟踪标志
?? 用来实现对文件中部分脚本的跟踪执行。 ?
7.4? 程序调试(续6)
?例:
???? # cat traced
???? date
???? echo $PATH | wc -c
???? # sh -x traced
???? +date
???? 1998年 11月 05日 星期四 17时 30分 08秒 CST
???? +echo? /bin:/usr/bin:/usr/fk/bin
????? /bin:/usr/bin:/usr/fk/bin
????? +wc? -c
????????? 25?????????????????????
7.4? 程序调试(续7)
?F? 详细跟踪与跟踪执行的组合
???? 整个程序的跟踪执行
???? 格式????
??sh? -vx? shprog
?? ·? 局部程序的跟踪执行
???? 格式????
??set?? -vx???? ——? 设置跟踪标志
??set? +vx???? ——? 关闭跟踪标志
7.5? Shell程序的应用
?F? Shell程序的定义
??? 若一个文件包含了一串简单命令串时,称为
命令文件;若一个文件包含了一组更为复杂的命
令组合(常常使用了Shell的条件命令、控制结构
和其它高级特性)时,就称之为Shell程序(或称
Shell过程)。通常情况下,两者的称呼并没有明
确的区别。
???? 在Shell程序设计语言里的基本操作是UNIX系
统命令,它是UNIX系统中最有生气的部分,而且
对于UNIX系统的使用极为重要。
7.5? Shell程序的应用(续)
?F? 何时使用Shell程序设计语言
??? 当一个问题的解决方法包含了许多UNIX系统
的标准命令操作时,可使用Shell程序设计语言;
? ·? 如果一个问题能用在UNIX系统中已建立的基
本操作所表示,则使用Shell程序设计语言能构成
更强的功能;
? ¸? 如果处理问题的基本数据是正文行或文件,
则Shell可描述一个很好的解决方法;若基本数据
是数字或字符,则使用Shell可能不是好办法;
? ¹? 使用Shell程序的最后一个准则是程序的开发
成本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值