Download presentation
Presentation is loading. Please wait.
1
第三讲 shell 程序设计
2
3.1 概述 shell是UNIX系统用用户与操作系统交互的最基本工具,实际上shell除了有命令解释执行的功能外,还具备有其他的功能,如:
系统环境的设置 输入输出的重新定向 shell程序语言的设计等。
3
3.1概述 在UNIX系统中使用shell程序设计,可以完成比较复杂并且自动执行的任务。UNIX系统上的shell程序在本质上是一种解释执行的脚本语言,使用的元素是UNIX系统的命令集,它与windows系统中的bat批处理文件原理相同,但是比批处理文件更强大,也更灵活。
4
3.1 概述 举例 # append.sh case $# in 1 ) cat >> data.txt;;
3.1 概述 举例 # append.sh case $# in 1 ) cat >> data.txt;; 2 ) cat $1 >> $2 ;; * ) echo “Incorrect usage ! ” ;; esac
5
3.1 概述 举例 for dir in cc work do echo “…. In $dir….” cd $dir
3.1 概述 举例 cd $HOME for dir in cc work do echo “…. In $dir….” cd $dir for file in *.[c] do ls –l $file done cd
6
3.2 Shell程序的执行方式 Shell程序有多种执行方式,比如,我们建立一个比较简单的shell程序脚本,文件保存命名为 test.sh,内容如下: date who ps 执行这个test.sh可以有多种方式。 1)将test.sh作为shell命令的执行参数来完成该shell的执行: $ sh test.sh 2)利用输入输出的重定向方式 $ sh <test.sh 3)直接执行该shell程序,但首先要保证该shell程序具备可执行的权限,可以用chmod来修改: chmod a+x test.sh, 之后在命令行执行它 $ test.sh
7
3.3 Shell程序的变量 Shell有以下几种基本类型的变量: shell定义的环境变量 用户定义的变量 位置参数 预定义变量
如果shell程序只能简单地执行一些命令,那shell的功能无疑是非常弱的,幸运的是,shell程序被设计为可以支持变量的使用,比如定义变量,应用变量的值等等。这使得shell程序具有异常强大的功能。需要注意的是,shell的变量只有字符串型,在shell程序中出现的数值计算都是基于字符串类型来完成的。 Shell有以下几种基本类型的变量: shell定义的环境变量 用户定义的变量 位置参数 预定义变量
8
3.3 Shell程序的变量:变量赋值 1)shell中的变量和变量赋值
shell 变量定义由字母开始,可以包含数字,字母和下划线,例如 var1, username,pass_word等。 变量的赋值可以在程序运行中进行,也可以在变量定义时进行,例如UNIX=“SYSTEM V”,如果字符串中间没有空格和制表符,则可以不要双引号。 值得注意的是B-shell中等号=的两边是不允许有空格的。
9
3.3 Shell程序的变量:变量访问 2)shell中变量的访问和参数替换 在shell程序中,或者是shell命令中,使用操作符$来对shell变量进行访问。例如,要显示某个变量时,可以输入: $ echo $UNIX (系统将会显示SYSTEM V ) 在某些场合下,为了明确表示对shell变量的引用,可以用花括弧{ }或者双引号将变量括起来,例如: $ echo ${UNIX} $ echo ${UNIX}Aaaaaa $ echo “$UNIX” is very good SYSTEM V SYSTEM VAaaaaa SYSTEM V is very good
10
3)shell中引号的说明: 单引号‘’、 双引号“”、 反引号`
(a)单引号’ :使用单引号时,shell将一对单引号之间的内容看成是纯粹的字符串信息,一对单引号之间可以包含更多的单引号。 you=”kkk” echo ‘this is just a ‘test’, can $you tell me the time ?’ 将会显示this is just a ‘test’, can $you tell me the time ?, 它不会将$you替换成“kkk“, 同时‘test’也是作为字符串内容来处理的。 (b)双引号“ : 它将双引号之间的特殊字符作为shell中的含义来解释。 $ file=unixshell $ echo “the content of ‘date’ is in $file” 这个例子将会显示 the content of wed Aug 16 16:20:12 is in unixshell,这个例子中,’date’被解释成了当前时间的返回值,$file被解释成了unixshell字符串。 (c)反引号` 用它来赋值时,表示变量中保存的是执行对应命令的结果。 name=`whoami` echo $name 这个时候显示的不是字符串whoami,而是执行字符串whoami的返回结果,当然,要先保证字符串是一个合法的命令。
11
4)变量的定义域 同其他的编程语言如C,pascal一样,shell的变量也有局部变量和全局变量的区别。通常在一个shell程序中,通过形如var1=abc方式定义的都是局部变量,只能在该shell程序的进程中起作用,要定义全局变量,需要在局部变量定义之后使用export 命令来将这个变量声明为全局的: export $var1 以下面的例子var.sh,我们来说明全局变量和局部变量的区别和使用 $ var1=csu $ echo $var1 $ sh $ exit $ export $var1 第三行,调用sh进入一个新的shell进程 第一个echo显示的是 csu,这是通常的用法 第四行的echo显示为空,因为var在这个进程中并没有进行定义 第五行,调用exit退出新建的shell回到原来shell的进程中 第六行的echo又能够正常显示了 第七行调用export,将var1定义为全局的,这样在新建的shell中,var1也能访问, 最后一行显示出csu
12
3.3 Shell程序的变量:环境变量 5)环境变量
shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,这些变量用户还可以重新定义,常用的shell环境变量有:
13
3.3 Shell程序的变量:环境变量 HOME:用于保存注册目录的完全路径名。 PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。 TERM:终端的类型。 UID:当前用户的标识符,取值是由数字构成的字符串。 PWD:当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化。 PS1:主提示符,在特权用户下,缺省的主提示符是“#”,在普通用户下,缺省的主提示符是“$”。 PS2:在shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“\”然后回车,或者当用户按回车键时shell判断出用户输入的命令没有结束时,显示这个辅助提示符,提示用户继续输入命令的其余部分,缺省的辅助提示符是“>”。
14
3.3 Shell程序的变量:位置变量 6)Shell中命令的位置变量
位置参数是一种在调用shell程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1,第二个替换$2,依次类推。$0是一个特殊的变量,它的内容是当前这个shell程序的文件名,所以,$0不是一个位置参数,在显示当前所有的位置参数时是不包括$0的。 #listargs.sh argv1 argv2 argv3 argv4 $ $ $2 $3 $4
15
3.3 Shell程序的变量:预定义变量 Bshell变量 CShell变量 变量的作用 $# $#argv 位置参数的个数 $*
预定义变量和环境变量相类似,也是在shell一开始时就定义了的变量,所不同的是,用户只能根据shell的定义来使用这些变量,而不能重定义它。所有预定义变量都是由$符和另一个符号组成的,常用的shell预定义变量有: Bshell变量 CShell变量 变量的作用 $# $#argv 位置参数的个数 $* 表示参数列表 $? $status 前一个命令返回的状态值 $$ 当前shell进程的pid值 $! 最近访问的后台进程pid值
16
3.3 Shell程序的变量:变量替换 7).Shell中的变量替换
替换的形式有三种,列举如下: $ {var:-word} 表示如果var已经被赋值,则取它的值,否则取word的值,但var不改变。 $ {var:=word} 表示如果var已经被赋值,则取它的值,否则取word的值,同时将word赋给 var。 $ {var:+word} 表示如果var已经被赋值,则取它的值,否则var变量置为空。
17
3.4 test命令的使用 在shell中经常要对某些变量的值进行判断来决定分支程序的走向,如同C中使用 if( a == 0) 一样。Shell中通过test命令来完成这个功能。 test的格式表示为: test expre 或者 test [expre] test命令的执行结果是,如果表达式为真,则返回真值0,否则返回非0的假值。 test命令可以对文件,字符串内容,整数n等变量进行测试。
18
3.4 test命令的使用 1)对文件特性的测试 语法: test [-dfrwxs] file
-e文件名:如果文件存在则为真 -r文件名:如果文件存在且可读则为真 -w文件名:如果文件存在且可写则为真 -x文件名:如果文件存在且可执行则为真 -s文件名:如果文件存在且至少有一个字符则为真 -d文件名:如果文件存在且为目录则为真 -f文件名:如果文件存在且为普通文件则为真 -c文件名:如果文件存在且为字符型特殊文件则为真 -b文件名:如果文件存在且为块特殊文件则为真
19
3.4 test命令的使用 例如: $ test –d /home/user && echo “directory exists”
$ test –x /home/user/sh1.sh || echo “sh1.sh dos not exist or is not runnable !” 判断文件/home/user/sh1.sh是否可执行,如果为假(||)则执行echo进行显示
20
3.4 test命令的使用 2)对字符串内容的测试 语法: test s (字符串s为有值时返回真,为空则返回假)
test -zs 与test s 相反,为空时返回真,不空则返回假 test s1 = s2 当字符串s1和s2相等时返回真,不相当则返回假 test s1 != s2 与test s1=s2相反。 例 x1=“005” x2 =5 ,进行字符串测试 #test “$x1” = “$x2” #echo $? 系统将显示0, 结果为假值,表示x1和x2不相等
21
3.4 test命令的使用 3)对于整数n的的测试 格式 test n1 [-eq/ne/it/ie/gt/ge] n2
它们分别表示n1和n2之间 相等 /不相等 /n1<n2 /n1<=n2 /n1>n2 /n1>=n2 时返回真值。 例 x1=“005” x2 =5 ,进行数字式测试 #test “$x1” -eq “$x2” #echo $? 系统将显示1, 结果为真值,表示数字x1和数字x2相等
22
3.5 条件控制语句 在结构化的程序设计中,三种基本的语句结构是顺序结构,分支结构,循环结构。其中的分支结构,在shell中常用if和case语句来实现。 1)if语句 if语句的分支可以有 无分支条件语句,二分支条件语句,多分支条件语句。 无分支条件语句格式如下: if [condition] then 命令1 命令2 … 命令n fi 当条件condition为真时,执行then后面的所有命令,condition为假则执行fi后面的语句。
23
3.5 条件控制语句 1)if语句 例:edit.sh if [ $#=1 ] then cp $1 $HOME/user1 fi
vi $1 exit 0
24
3.5 条件控制语句 多分支结构:分支大于2的条件语句。 if [condition1] then elif [contition2]
elif [condition3] … else command_n fi 二分支条件语句: 格式为 if then else 结构 if [condition] then 命令1 命令2 else. 命令n fi
25
3.5 条件控制语句 例:假设一个连续运行系统,将建立错误记录文件errorfile 并不断写入错误信息。现在要求编写一个shell程序来产生定时错误日志文件datelog,能在datelog 中体现每个时间段中的错误信息 # checkerr.sh To check error information with time stamp !!! date >> datelog if test –r errorfile then cat errorfile >> datelog rm errorfile else echo “No error occurs during this hour!“ >> datelog fi
26
3.5 条件控制语句 2)case语句 可以实现多选一的控制结构 case语句的语法为: case word in 模式1 ) 命令 ;;
模式2 ) 命令 ;; 模式3 ) 命令 ;; esac 注意,在case中,每个命名命令的结束用;;表示模式匹配已经完成,不再匹配其他的模式,相当于C中的break。
27
3.5 条件控制语句 例:编写一段shell程序,根据执行时获取的当前时间显示不同的问候信息 # hello.sh
hour = `date +%H` case $hour in 0[1-9] | 1[01] ) echo “Good morining !!” ;; 1[234567] ) echo “Good afternoon !!” ;; ) echo “Good evening !! ” ;; esac
28
3.5 条件控制语句 例:利用shell的位置变量参数编写一个shell,当只有一个参数时,从键盘输入文本保存到data.txt中,当有两个参数时,将参数1代表的文件内容添加到参数2表示的文件,其他情况则给出错误提示信息 # append.sh case $# in 1 ) cat >> data.txt;; 2 ) cat $1 >> $2 ;; * ) echo “Incorrect usage ! ” ;; esac
29
3.6 循环语句 shell中的循环有for和while两种循环方式。 1)for的语法格式为: for var
in list-of-vars do command1 command2 … commandn done for的语法说明为:shell程序扫描变量列表list-of-vars,将其中的每一个字依次存放在var中,并执行do和done之间的语句。如果list-of-vars中有n个字,则这个for循环将执行n次。
30
3.6 循环语句 在需要的时候,也可以进行for循环的嵌套。 见下面的例子: cd $HOME for dir in cc work do
echo “…. In $dir….” cd $dir for file in *.[c] do ls –l $file done cd
31
3.6 循环语句 2)while循环 while - do - done结构 while循环中,只要循环条件为真就一直循环下去。 格式:
while [condition] do command1 command2 ….. done
32
3.6 循环语句 3)until循环 until-do-done
until循环和while循环类似,所不同的是until循环只要循环条件为假,就一直执行循环体。 格式: until [condition] do command1 commandn done 如果第一次执行时,循环条件condition就为真,那循环体将得不到执行。 同时还要注意,必须在程序中设置条件condition为真的因素,否则循环将一直进行下去,从而进入了死循环。
33
3.6 循环语句 例:编写shell程序一次性创建若干个新文件,如file1, file2, file3. . . . . . file10
两个相关命令 touch 命令,改变文件的访问和修改时间 格式: touch [option][time] filename [option] -a 只修改文件的访问时间 -m 只修改文件的修改时间 当指定文件filename不存在,则创建一个具有默认权限和当前时间的新文件
34
3.6 循环语句 例:编写shell程序一次性创建若干个新文件,如file1, file2, file3. . . . . . file10
两个相关命令 expr 命令,对shell变量进行算术运算的操作,因为shell变量都是字符型,进行算术运算必须使用expr命令 shell中错误的算术运算: #count = 9 #count = $count + 11 #echo count shell中正确的算术运算: #count = 9 #count = `expr $count + 11` #echo count 系统将显示:9+11 系统将显示:20
35
3.6 循环语句 例:编写shell程序一次性创建若干个新文件,如file1, file2, file3. . . . . . file10
# genfiles.sh NUMBER = 1 While [ $NUMBER –lt 11] do touch file$NUMBER NUMBER = `expr $NUMBER + 1` done
36
3.7无条件控制语句break和continue
break用于立即终止当前循环的执行,而contiune用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在do和done之间才有效。
37
3.8 函数 在shell中还可以定义函数。函数实际上也是由若干条shell命令组成的,因此它与shell程序形式上是相似的,不同的是它不是一个单独的进程,而是shell程序的一部分。函数定义的基本格式为: functionname { 若干命令行 }
38
3.8函数 函数使用: 1、调用函数之前,必须先定义函数。 2、函数的参数的传递:functionname para1 para2 …. 3、在函数内部参数的读取: $0-$9 , $#(参数总个数) 4、函数的返回值:可能使用return命令返回数字值;要返回字符串值,可以字符串保存在一个全局性的变量中,该变量在函数结束后能被外界使用;如果没有使用return命令,则函数返回值是函数中最后执行的一条命令的退出状态码。 5、变量使用:函数内部声明的变量默认为全局变量,使用local关键字声明的变量为局部变量(如 local var=“var”)。如果局部变量与全局变量同名,则在函数内部局部变量覆盖全局变量。 6、返回值的获取,当执行完函数后,函数的返回值被存放在$?中,可以通过它来获取函数的返回值。
39
3.8 函数 举例 执行结果如下: # sh hello.sh hi #HELLO.sh function hello( )
{ echo “hi” } hello echo $? 执行结果如下: # sh hello.sh hi
40
3.8 函数 举例 #This is a example for testing the return value of function
function fun() { return 10 } fun echo $? exit 0 执行结果如下: # sh fun.sh 10
41
3.8 函数 举例 执行结果如下: # sh funsample1.sh 30 #funsample1.sh function add( )
{ declare -i sum sum=$1+$2 return $sum } add 10 20 echo $? 执行结果如下: # sh funsample1.sh 30
42
3.8 函数 举例 function find_file() { if [ $# -lt 1 ];then return 1; fi if [ find -name $1 –print2>/dev/null ] then : else echo "File $1 not found" fi }
43
3.8 函数 举例 #_MAIN_ if [ $# -lt 1 ];then echo "Usage: $0 filename" return 1; fi for loop in do find_file $loop done
44
3.8 函数 举例 #_MAIN_ if [ $# -lt 1 ];then echo "Usage: $0 filename" return 1; fi for loop in do find_file $loop done
45
3.8 函数 举例 #test1.sh function hello() { echo “hi” } #test.sh
#注意.后面要有一个空格 . test1.sh hello 执行结果: hi
46
3.9 命令分组 在shell中有两种命令分组的方法:“()”和“{}”,前者当shell执行()中的命令时将再创建一个新的子进程,然后这个子进程去执行圆括弧中的命令。当用户在执行某个命令时不想让命令运行时对状态集合(如位置参数、环境变量、当前工作目录等)的改变影响到下面语句的执行时,就应该把这些命令放在圆括弧中,这样就能保证所有的改变只对子进程产生影响,而父进程不受任何干扰;{}用于将顺序执行的命令的输出结果用于另一个命令的输入(管道方式)。当我们要真正使用圆括弧和花括弧时(如计算表达式的优先级),则需要在其前面加上转义符(\)以便让shell知道它们不是用于命令执行的控制所用。
47
3.10 Shell程序调试 shell程序是一种解释性语言,它的执行是逐行进行的,程序中是否有语法错误,不执行到那一行系统是无法知道的。C,pascal等高级语言是有编译过程的,程序中的语法错误在编译阶段就能检测出来,因此比shell更容易调试 shell程序通常有三种调试方法: 1)交互式调试 shell程序中使用的命令都能在命令行中运行,所以对于一些不很熟悉的命令和语法可以先用命令进行验证,然后再编写到shell程序中,这种调试方法称为交互式调试,也是最简单的一种调试方法。
48
3.9 Shell程序调试 2)在编辑过程中不断调试执行所编辑的shell程序
在UNIX系统中可以打开多个工作窗口。我们可以在一个窗口中用vi等编辑器进行编辑,然后在另一个连接窗口中执行该shell程序,这样可以随时观察到已经编写的部分是否正确。最终完成这个shell程序的编写。 3)用shell程序提供的跟踪功能进行调试 shell程序可以使用 -v -x 选项对shell程序进行跟踪 -v:当读入shell输入行时把它们显示出来,完成详细跟踪。Shell程序在完成这段程序执行时首先逐行读入执行的命令,并在标准输出上显示该命令要执行的实际内容,然后执行该命令。如果没有语法错误,执行将一直进行下去直到完成shell的执行。 -x:执行命令前先把命令和它们的参数显示出来
49
3.9 Shell程序调试 假设有这么一个简单的shell,叫test1.sh date echo $PATH
我们用-v参数来调试, 执行sh -v test1.sh那么输出就应该是: Mon Sep 8 9:55:01 Linux echo $PATH /usr/bin:/usr/ucb/bin:/home/user1 shell在执行date前先显示该命令然后显示date的执行结果,接着显示echo $PATH以及它的执行结果。 如果用-x参数来执行这个shell,执行 sh -x test1.sh则系统的输出将是: +date Mon Sep 8 9:55:01 Linux +echo /usr/bin:/usr/ucb/bin:/home/user1 /usr/bin:/usr/ucb/bin:/home/user1 date这一行没有参数,所以只显示命令 echo这一行有参数$path,被直接替换成了参数的值。
50
3.9 Shell程序调试 在调试一个比较大的shell时,没有必要对整个shell程序都进行跟踪,可以只对其中较为负责的部分进行跟踪,这时可以通过 set –v ……… set +v或者set –x …………set +x来把需要跟踪的部分包含进来。
51
3.10 Shell编程示例 1.使用for循环语句编写Bshell程序,完成显示用户注册目录下a_sub, b_sub子目录下的所有C程序源文件和目标文件的列表
52
3.10 Shell编程示例 # showCfile.sh if test -d $HOME/a_sub then
echo "-- the .c and .obj files in $HOME/a_sub: --" for filename in `ls $HOME/a_sub` do case $filename in *.c) echo $filename;; *.obj) echo $filename;; esac done else echo "$HOME/a_sub does not exist!!" fi
53
3.10 Shell编程示例 if test -d $HOME/b_sub then
echo "--- the .c and .obj files in $HOME/b_sub: ---" for filename in `ls $HOME/b_sub` do case $filename in *.c) echo $filename is a C source file!;; *.obj) echo $filename is an Object file!;; esac done else echo "$HOME/b_sub does not exist!!" fi
54
3.10 Shell编程示例 2.连续输入若干个名字到文件file.names中保留
read 当Bsh遇到一个read语句时,在标准输入文件中读取数据直到一个换行符。此时Shell在解释输入行时,不进行文件名或变量的替换,只是简单地删除多余的空格。然后Shell将输入行的第一个字的内容给变量1,第二个给变量2,直到所有变量都赋上值或是输入行为空。若输入行中字的个数超过变量个数,Shell将把输入行中剩余的所有字的内容都赋给最后一个变量。当变量个数多于输入行字的个数时候,多于的变量将赋一个空值。输入行的每一个字是由空格分隔的一个字母和数字组成的字符串。可以通过重定向的方式从文件中读字符串。
55
3.10 Shell编程示例 ans=yes until ["$ans" = no ]
do echo Enter a name read name echo $name >> file.names echo "Continue?" echo Enter yes or no read ans done
56
3.10 Shell编程示例 3. 持续检测文件abc.txt是否存在
57
3.10 Shell编程示例 while [test -r abc.txt] do
echo "file abc.txt has not beed deleted !“ sleep 10 done echo "file abc.txt has beed deleted !"
58
3.10 Shell编程示例 4. 统计文件file的行数
59
3.10 Shell编程示例 count=0 while read LINE do count=`expr $count + 1`
done < file echo $count 或者 cat file | wc -l
60
3.10 Shell编程示例 5. 编写shell程序files.sh实现如下功能:从命令行输入1到3个文件名,如果只输入一个文件名,则从键盘录入信息,保存到该文件中;如果输入两个文件名,则先显示两个文件的内容,再将文件1的内容追加到文件2的末尾;如果输入3个文件名,则将文件1和文件2的内容合并覆盖到文件3上。
61
case $# in 1) cat >> $1;; 2) cat <$1 >>$2;; 3) cat $1 $2 >>$3;; *) echo "To many param" esac if [test $# -eq 1 ] then cat>>$1 elif $#=2 cat <$1 >>$2 elif $#=3 cat $1 $2 >>$3 else echo “error” fi
62
3.10 Shell编程示例 6.为了便于系统管理员对磁盘分配的管理,请编写一段shell程序,当文件系统/home的占用空间量改变时,给出相应的信息提示。要求/home占用量在系统磁盘中为: 1)小于50%时,提示“用户系统文件磁盘使用负荷量小”。 2)大于50%,小于90%时,提示“用户文件系统磁盘使用负荷量正常” 3)大于90%时,提示“用户文件系统磁盘使用负荷量偏大”。
63
3.10 Shell编程示例 bc 一个简单的计算器。bc是一个支持交互的表达式计算的语言,其格式类似于C语言
命令行 echo 1+33*3 | bc 也能计算出1+33×3=100。 scale n 计算的精度 du 显示文件或目录所占的磁盘空间 -s 只显示设定文件目录的空间总量 -r 如果文件不能读取,则显示出提示信息 -a 可以接收多个文件,并一一显示所占的磁盘空间
64
3.10 Shell编程示例 echo echo "--- Disk Usage Condition ---"
used_disk=`du -s /home | cut -f1` echo "Used Blocks: $used_disk" free_disk=`df | head –2 |tail -1 | tr -s "[ ]" | cut -f4 -d" "` echo "Free Blocks: $free_disk" total_disk=`expr $used_disk + $free_disk` echo "total blocks:$total_disk" echo "--- disk usage ratio ---"
65
3.10 Shell编程示例 #计算出磁盘的利用率 ratio=`echo "scale=6; $used_disk*100/$total_disk" | bc` echo -e "usage ratio: $ratio%" if [ `expr "$ratio < 50"` ] then echo "用户文件系统磁盘使用负荷小" elif [ `expr "$ratio > 90"`] echo "用户文件系统磁盘使用负荷偏大" else echo "用户文件系统磁盘使用负荷正常" fi echo
66
3.10 Shell编程示例 7. 编写一个shell程序:根据从键盘输入的学生成绩,显示相应的成绩标准。
67
echo -e "Please enter the score:"
while read SCORE do case $SCORE in ?|[1-5]? ) echo "Failed!" echo "Please enter the next score:";; 6?) echo "Passed!" 7?) echo "Medium!" 8?) echo "Good!" 9?|100) echo "Great!" *) exit;; esac done
68
3.10 Shell编程示例 8. 假设文件score.txt中保存了三个班级的学生成绩,编写一段shell程序来计算3个班级的学生数目和平均成绩。
69
3.10 Shell编程示例 #!/bin/sh #Averaterscore.sh SCORE1=0 SCORE2=0 SCORE3=0
NUMBER1=0 NUMBER2=0 NUMBER3=0 SAVED_IFS=$IFS IFS=: INPUT_FILE=score.txt
70
3.10 Shell编程示例 while read NAME CLASS SCORE #循环读入各行 do case $CLASS in
class1) NUMBER1=`expr $NUMBER1+1` SCORE1=`expr $SCORE1+$SCORE`;; class2) NUMBER2=`expr $NUMBER2+1` SCORE2=`expr $SCORE2+$SCORE`;; class3) NUMBER3=`expr $NUMBER3+1` SCORE3=`expr $SCORE3+$SCORE`;; *) echo "`basename $0`:Unknow class $CLASS" ;; esac done < INPUT_FILE
71
3.10 Shell编程示例 #开始计算平均分数 SCORE1=`echo "scale=2; $SCORE1/$NUMBER1" | bc` SCORE2=`echo "scale=2; $SCORE2/$NUMBER2" | bc` SCORE3=`echo "scale=2; $SCORE3/$NUMBER3" | bc` #显示计算的结果 echo " class student num average score" echo "====================================================" echo " $NUMBER $SCORE1" echo " $NUMBER $SCORE2" echo " $NUMBER $SCORE3" IFS=$SAVED_IFS
72
3.10 Shell编程示例 9.编写一段Shell程序完成:根据从键盘输入的学生学号,到成绩表文件中查找对应的成绩,并进行显示。成绩表的定义如下 score.dat 001|94 003|93 … ... 123|88
73
ans=y until [ "$ans" = n ] do echo "Enter a Student number:" read number echo The inputed number is:${number} count=`grep ${number} score.dat | wc -l` echo the Count found is ${count} if test "$count" -eq 1 then score=`grep ${number} score.dat | cut -d\| -f2` echo The score is: ${score} else echo "Can not found this number !!" fi echo "Continue?" echo "Enter y(yes) or n(no)" read ans done
74
3.10 Shell编程示例 10. 在不同数据库之间进行数据的导入导出过程中,会出现数据不一致性的问题,为了避免这种情况,设计一个Shell程序,能对数据源数据中不一致的问题进行检验,并进行处理。 如:数据库1 表a内容为 a b c c d 导出的数据文件为a.dat,内容为 a|b|c c|d 将a.dat数据文件导入数据库2表a中,内容为: a b c c d 数据库2表a的内容发生改变
75
3.11 用户工作环境设置 Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。
76
3.11 用户工作环境设置 这些变量是用户在登录时进行赋值的,由shell统一维护,在用户注销时自动撤销。这些变量大部分是用户的基本的永久性变量,在用户工作时是不变的。但也有一部分变量是为了特殊目的而设定的,这些变量对用户有很大的针对性,同时也为用户提供了一定的自由度,因此它们允许用户根据自己的需要自行修改和调整。 Dos用户通常都知道,在系统启动时会自动执行启动盘根目录下的autoexec.bat文件(如果有这个文件)。这个文件可以完成PATH, PROMPT等环境变量的设置。同样的,UNIX系统下也有这种文件,而且通常不止一个,而是成一组的好几个文件。当然,根据用户设置的登录后使用的shell类型的不同,这些文件也有所不同。如果使用bsh,一般会有.bsh_profile, .bshrc, .bsh_logout等文件,如果是cshell,会有.cshrc这个文件,但是作用基本是相同的,都是设定用户缺省的环境变量。这些文件中的内容用户可以根据需要进行修改,以设成自己需要的内容。
77
3.11 用户工作环境设置 2)Bshell的环境变量
b shell是使用最广泛的UNIX系统,我们可以了解一下bshell的环境变量的设置。 在用户目录下有.bash_profile, .bashrc, .bash_logout三个和环境变量相关的文件,其中.bash_profile就相当于dos下面的autoexec.bat,我们来看看一个典型的.bash_profile的内容:
78
3.11 用户工作环境设置 # .bash_profile # Get the aliases and functions
if [ -f ~/.bshrc ] then . ~/.bshrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin echo "welcome Mr test, you can work well under Bshell" export PATH
79
3.11 用户工作环境设置 它在执行的时候会调用.bshrc, 内容如下: # .bshrc
# User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi
80
3.11 用户工作环境设置 这个shell会继续调用/etc/bashrc这个文件,在这个shell中将设置环境变量。正常登录后,一个Bshell的环境大致如下所示: INPUTRC='/etc/inputrc' USER='test' MAIL=‘/var/spool/mail/test’ #当前用户的邮件存放目录 HOSTNAME=‘linux9’ #主机的名称 OLDPWD='/home/test' HOME=‘/home/test‘ #当前用户主目录 SUPPORTED='zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en' G_BROKEN_FILENAMES='1' PS1=‘$ ’ #基本提示符,对于root用户是#,对于普通用户是$ PS2=‘> ’ #附属提示符,默认是“>”
81
3.11 用户工作环境设置 LOGNAME=‘test’ #当前用户的登录名 _='clear'
COLORS='/etc/DIR_COLORS' TERM='ansi' PPID='3296' PATH='/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin' REMOTEHOST=' ' LANG=‘en_US.UTF-8’ #和语言相关的环境变量 HISTSIZE=‘1000’ #保存历史命令记录的条数 SHELL=‘/bin/bsh’ #当前用户用的是哪种Shell PWD='/home/test/t‘ 其他的shell如Cshell,Kshell均是大同小异
82
3.11 用户工作环境设置 相关文件 /etc/profile
/home/liheng**/.bash_profile /home/liheng**/.bashrc /home/liheng**/.bash_logout 在这里修改的内容是对登录用户起作用的
83
作业 1、完成实验二,上机 2、查看文件 /etc/profile /home/liheng**/.bash_profile
/home/liheng**/.bashrc /home/liheng**/.bash_logout
Similar presentations