第三讲 shell 程序设计.

Slides:



Advertisements
Similar presentations
Linux 环境及 Shell 程序 操作系统实验 1. 二、 Shell 编程与进程通信 常用 shell 命令 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、
Advertisements

上課教材 Database Slide Windows筆電 (32 bit)
第七章 操作系统接口 7.1 联机用户接口 7.2 Shell命令语言 7.3 系统调用 7.4 UNIX系统调用 7.5 图形用户接口.
第一章 C语言概述 计算机公共教学部.
Linux 的檔案管理.
TQC+ 物件導向程式認證-JAVA.
LINUX 环境下程序开发基础 曙光用户培训课程系列 课程时间:1.5小时 更新日期:2008年3月.
為有特殊教育需要學生 提供特別評估安排 教育局 2011年12月2日.
資訊安全與系統管理 2013/3/13 Chien wei lin.
Chapter 4 流程控制.
UNIX系統與資料庫安裝 Why UNIX 常用的工具程式介紹 資料庫的安裝.
System Administration Practice Homework 2: Shell Programming
Unit 2 What should I do?.
Ch07 PHP程式基礎 網頁程式設計.
Linux 的進階檔案處理.
Confidential Property
程式設計實作.
Vi 編輯器的練習的說明 因為本課程的實習課是Unix 的工作環境。過去的經驗告訴我,如果你完全未用過Unix 的指令及其 vi 編輯器,你將很難跟上進度,希望學員一定要預先作練習。我們提供了Unix 指令的簡介,以及 vi 編輯器的介紹 ( 請参閱網站中的13&14-unix.pdf 為其講義;13-unix.exe、14-fortran.exe則為其課程錄影.
NUIST HPC使用讲座 ——代码调试 刘建宇
Chapter 1 複習.
第 2 章 上機使用 Unix/Linux 內容: 操作介面 主機連線 登入主機 認識系統環境 使用者常用命令.
台灣大學計算機及資訊網路中心 教學研究組 張傑生
第7章:文件共享 与远程控制——回顾 第8章:bash脚本编程 本章教学目标: 了解shell程序的基本结构 网络文件系统NFS的概念
Shell Script 程式設計.
Shell程序设计 曙光信息产业股份有限公司.
Chinese IIAB (IIA +IIB)
第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本
Linux 基础与常用命令简介 生物信息学培训班 杭州,2018年1月18日 周银聪.
第3章 語法入門 第一個Java程式 文字模式下與程式互動 資料、運算 流程控制.
C 程式設計— 控制敘述 台大資訊工程學系 資訊系統訓練班.
程序讲解 第一题: 将指定文件的m行到n行字符写到显示屏上,m和n值从键盘输入。 运行时输入及结果: please enter m,n:
第二天 计算机基础技能培训 (一)linux基础知识
Function.
C 語言簡介 - 2.
曙光集群简明使用手册 技术支持中心.
新觀念的 VB6 教本 第七章 讓程式轉彎的控制敘述.
Linux基本操作 程設實習課 ( 2/25 ).
伺服器探索營 Day 1 指導老師: 張啟中 (JohnAxer) 教學助理:
Introduction to the C Programming Language
本章中將會更詳細地考慮有關重複的概念,並且會 介紹for和do…while等兩種用來控制重複的敘述 式。 也將會介紹switch多重選擇敘述式。 我們會討論直接和迅速離開某種控制敘述式的 break敘述式,以及用來跳過重複敘述式本體剩餘 部份的continue敘述式。 本章會討論用來組合控制條件的邏輯運算子,最後.
第12章 shell编程基础 本章主要介绍shell编程的基础知识。shell脚本的执行类似于Linux下的任何其他命令,脚本可以包含复杂的逻辑,也可以包含一系列Linux命令行指令。在一个shell程序内可以运行其他shell脚本。通过本章的学习,读者可以学到如何使用bash(最流行的Linux.
雲端計算.
檔案類型介紹 Linux 的檔案類型 目錄: 用ls –F時檔名後面有/,螢幕列出目錄時為藍色 可執行檔: 壓縮檔: 連結檔:
Week 2: 程式設計概念與 演算法的效能評估
第二章 UNIX系统安装与常用命令.
第六章 shell 程序调试 一. 程序执行状态跟踪 程序: -n 读取命令, 但不执行. 主要用于跟踪程序流程是
如何有效率的學習Linux 培養組合能力 多用程式, 少寫程式 從錯誤訊息中學習 養成略讀 “各種文件” 加強英文基本閱讀能力 勤作筆記
软件工程 第四章 软件设计 软件过程设计技术与工具.
程式結構&語法.
第二章 流编辑器sed 一. 什么是流编辑器? 流编辑器是一种流水线型的、非交互式
第三章 UNIX的文件与目录.
MATLAB 程式設計入門篇 初探MATLAB
UNIX指令-檔案與目錄操作.
for 迴圈 while迴圈 do-while迴圈 break 與 continue goto 與 標籤 程式觀摩
C语言环境配置.
杨振伟 清华大学 第一讲:Linux环境下编程(1)
Compute System Administration Homework 2: Shell Script
1.3操作系统提供的服务和用户接口 操作系统提供的用户接口 程序接口与系统调用 操作接口与系统程序
台灣大學計算機及資訊網路中心 教學研究組 張傑生
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
程序管理 蘇偉順助教.
实验二:添加Linux系统调用及熟悉常见系统调用
粒子物理与核物理实验中的数据分析 杨振伟 清华大学 第1讲:Linux环境下的编程.
Arguments to the main Function and Final Project
杨振伟 清华大学 第一讲:Linux环境下编程(1)
C语言基本语句 判断循环.
劉庠宏、林合治編著 國立高雄大學應用數學系 2005年3月1日
第六章 文件系统与文件管理 6.4 Linux文件管理 1、比较MS DOS 与 Linux的目录结构 一、Linux文件系统的树形结构
Presentation transcript:

第三讲 shell 程序设计

3.1 概述 shell是UNIX系统用用户与操作系统交互的最基本工具,实际上shell除了有命令解释执行的功能外,还具备有其他的功能,如: 系统环境的设置 输入输出的重新定向 shell程序语言的设计等。

3.1概述 在UNIX系统中使用shell程序设计,可以完成比较复杂并且自动执行的任务。UNIX系统上的shell程序在本质上是一种解释执行的脚本语言,使用的元素是UNIX系统的命令集,它与windows系统中的bat批处理文件原理相同,但是比批处理文件更强大,也更灵活。

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

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

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

3.3 Shell程序的变量 Shell有以下几种基本类型的变量: shell定义的环境变量 用户定义的变量 位置参数 预定义变量 如果shell程序只能简单地执行一些命令,那shell的功能无疑是非常弱的,幸运的是,shell程序被设计为可以支持变量的使用,比如定义变量,应用变量的值等等。这使得shell程序具有异常强大的功能。需要注意的是,shell的变量只有字符串型,在shell程序中出现的数值计算都是基于字符串类型来完成的。 Shell有以下几种基本类型的变量: shell定义的环境变量 用户定义的变量 位置参数 预定义变量

3.3 Shell程序的变量:变量赋值 1)shell中的变量和变量赋值 shell 变量定义由字母开始,可以包含数字,字母和下划线,例如 var1, username,pass_word等。 变量的赋值可以在程序运行中进行,也可以在变量定义时进行,例如UNIX=“SYSTEM V”,如果字符串中间没有空格和制表符,则可以不要双引号。 值得注意的是B-shell中等号=的两边是不允许有空格的。

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

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的返回结果,当然,要先保证字符串是一个合法的命令。

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

3.3 Shell程序的变量:环境变量 5)环境变量 shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,这些变量用户还可以重新定义,常用的shell环境变量有:

3.3 Shell程序的变量:环境变量 HOME:用于保存注册目录的完全路径名。 PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。 TERM:终端的类型。 UID:当前用户的标识符,取值是由数字构成的字符串。 PWD:当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化。 PS1:主提示符,在特权用户下,缺省的主提示符是“#”,在普通用户下,缺省的主提示符是“$”。 PS2:在shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“\”然后回车,或者当用户按回车键时shell判断出用户输入的命令没有结束时,显示这个辅助提示符,提示用户继续输入命令的其余部分,缺省的辅助提示符是“>”。

3.3 Shell程序的变量:位置变量 6)Shell中命令的位置变量 位置参数是一种在调用shell程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1,第二个替换$2,依次类推。$0是一个特殊的变量,它的内容是当前这个shell程序的文件名,所以,$0不是一个位置参数,在显示当前所有的位置参数时是不包括$0的。 #listargs.sh argv1 argv2 argv3 argv4 $0 $1 $2 $3 $4

3.3 Shell程序的变量:预定义变量 Bshell变量 CShell变量 变量的作用 $# $#argv 位置参数的个数 $* 预定义变量和环境变量相类似,也是在shell一开始时就定义了的变量,所不同的是,用户只能根据shell的定义来使用这些变量,而不能重定义它。所有预定义变量都是由$符和另一个符号组成的,常用的shell预定义变量有: Bshell变量 CShell变量 变量的作用 $# $#argv 位置参数的个数 $* 表示参数列表 $? $status 前一个命令返回的状态值 $$ 当前shell进程的pid值 $! 最近访问的后台进程pid值

3.3 Shell程序的变量:变量替换 7).Shell中的变量替换 替换的形式有三种,列举如下: $ {var:-word} 表示如果var已经被赋值,则取它的值,否则取word的值,但var不改变。 $ {var:=word} 表示如果var已经被赋值,则取它的值,否则取word的值,同时将word赋给 var。 $ {var:+word} 表示如果var已经被赋值,则取它的值,否则var变量置为空。

3.4 test命令的使用 在shell中经常要对某些变量的值进行判断来决定分支程序的走向,如同C中使用 if( a == 0) 一样。Shell中通过test命令来完成这个功能。 test的格式表示为: test expre 或者 test [expre] test命令的执行结果是,如果表达式为真,则返回真值0,否则返回非0的假值。 test命令可以对文件,字符串内容,整数n等变量进行测试。

3.4 test命令的使用 1)对文件特性的测试 语法: test [-dfrwxs] file -e文件名:如果文件存在则为真 -r文件名:如果文件存在且可读则为真 -w文件名:如果文件存在且可写则为真 -x文件名:如果文件存在且可执行则为真 -s文件名:如果文件存在且至少有一个字符则为真 -d文件名:如果文件存在且为目录则为真 -f文件名:如果文件存在且为普通文件则为真 -c文件名:如果文件存在且为字符型特殊文件则为真  -b文件名:如果文件存在且为块特殊文件则为真

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进行显示

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不相等

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相等

3.5 条件控制语句 在结构化的程序设计中,三种基本的语句结构是顺序结构,分支结构,循环结构。其中的分支结构,在shell中常用if和case语句来实现。 1)if语句 if语句的分支可以有 无分支条件语句,二分支条件语句,多分支条件语句。 无分支条件语句格式如下: if [condition] then 命令1 命令2 … 命令n fi 当条件condition为真时,执行then后面的所有命令,condition为假则执行fi后面的语句。

3.5 条件控制语句 1)if语句 例:edit.sh if [ $#=1 ] then cp $1 $HOME/user1 fi vi $1 exit 0

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

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

3.5 条件控制语句 2)case语句 可以实现多选一的控制结构 case语句的语法为: case word in 模式1 ) 命令 ;; 模式2 ) 命令 ;; 模式3 ) 命令 ;; esac 注意,在case中,每个命名命令的结束用;;表示模式匹配已经完成,不再匹配其他的模式,相当于C中的break。

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

3.5 条件控制语句 例:利用shell的位置变量参数编写一个shell,当只有一个参数时,从键盘输入文本保存到data.txt中,当有两个参数时,将参数1代表的文件内容添加到参数2表示的文件,其他情况则给出错误提示信息 # append.sh case $# in 1 ) cat >> data.txt;; 2 ) cat $1 >> $2 ;; * ) echo “Incorrect usage ! ” ;; esac

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次。

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

3.6 循环语句 2)while循环 while - do - done结构 while循环中,只要循环条件为真就一直循环下去。 格式: while [condition] do command1 command2 ….. done

3.6 循环语句 3)until循环 until-do-done until循环和while循环类似,所不同的是until循环只要循环条件为假,就一直执行循环体。 格式: until [condition] do command1 commandn done 如果第一次执行时,循环条件condition就为真,那循环体将得不到执行。 同时还要注意,必须在程序中设置条件condition为真的因素,否则循环将一直进行下去,从而进入了死循环。

3.6 循环语句 例:编写shell程序一次性创建若干个新文件,如file1, file2, file3. . . . . . file10 两个相关命令 touch 命令,改变文件的访问和修改时间 格式: touch [option][time] filename [option] -a 只修改文件的访问时间 -m 只修改文件的修改时间 当指定文件filename不存在,则创建一个具有默认权限和当前时间的新文件

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

3.6 循环语句 例:编写shell程序一次性创建若干个新文件,如file1, file2, file3. . . . . . file10 # genfiles.sh NUMBER = 1 While [ $NUMBER –lt 11] do touch file$NUMBER NUMBER = `expr $NUMBER + 1` done

3.7无条件控制语句break和continue break用于立即终止当前循环的执行,而contiune用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在do和done之间才有效。

3.8 函数 在shell中还可以定义函数。函数实际上也是由若干条shell命令组成的,因此它与shell程序形式上是相似的,不同的是它不是一个单独的进程,而是shell程序的一部分。函数定义的基本格式为: functionname    {    若干命令行    }

3.8函数 函数使用:   1、调用函数之前,必须先定义函数。   2、函数的参数的传递:functionname para1 para2 ….   3、在函数内部参数的读取: $0-$9 , $@(所有参数) $#(参数总个数) 4、函数的返回值:可能使用return命令返回数字值;要返回字符串值,可以字符串保存在一个全局性的变量中,该变量在函数结束后能被外界使用;如果没有使用return命令,则函数返回值是函数中最后执行的一条命令的退出状态码。   5、变量使用:函数内部声明的变量默认为全局变量,使用local关键字声明的变量为局部变量(如 local var=“var”)。如果局部变量与全局变量同名,则在函数内部局部变量覆盖全局变量。   6、返回值的获取,当执行完函数后,函数的返回值被存放在$?中,可以通过它来获取函数的返回值。

3.8 函数 举例 执行结果如下: # sh hello.sh hi #HELLO.sh function hello( ) {      echo “hi” } hello echo $? 执行结果如下: # sh hello.sh hi

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

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

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 }

3.8 函数 举例 #_MAIN_         if [ $# -lt 1 ];then                 echo "Usage: $0 filename"                 return 1;         fi         for loop in $@         do                 find_file $loop         done

3.8 函数 举例 #_MAIN_         if [ $# -lt 1 ];then                 echo "Usage: $0 filename"                 return 1;         fi         for loop in $@         do                 find_file $loop         done

3.8 函数 举例 #test1.sh function hello() { echo “hi” } #test.sh #注意.后面要有一个空格 . test1.sh hello 执行结果: hi

3.9 命令分组 在shell中有两种命令分组的方法:“()”和“{}”,前者当shell执行()中的命令时将再创建一个新的子进程,然后这个子进程去执行圆括弧中的命令。当用户在执行某个命令时不想让命令运行时对状态集合(如位置参数、环境变量、当前工作目录等)的改变影响到下面语句的执行时,就应该把这些命令放在圆括弧中,这样就能保证所有的改变只对子进程产生影响,而父进程不受任何干扰;{}用于将顺序执行的命令的输出结果用于另一个命令的输入(管道方式)。当我们要真正使用圆括弧和花括弧时(如计算表达式的优先级),则需要在其前面加上转义符(\)以便让shell知道它们不是用于命令执行的控制所用。

3.10 Shell程序调试 shell程序是一种解释性语言,它的执行是逐行进行的,程序中是否有语法错误,不执行到那一行系统是无法知道的。C,pascal等高级语言是有编译过程的,程序中的语法错误在编译阶段就能检测出来,因此比shell更容易调试 shell程序通常有三种调试方法: 1)交互式调试 shell程序中使用的命令都能在命令行中运行,所以对于一些不很熟悉的命令和语法可以先用命令进行验证,然后再编写到shell程序中,这种调试方法称为交互式调试,也是最简单的一种调试方法。

3.9 Shell程序调试 2)在编辑过程中不断调试执行所编辑的shell程序 在UNIX系统中可以打开多个工作窗口。我们可以在一个窗口中用vi等编辑器进行编辑,然后在另一个连接窗口中执行该shell程序,这样可以随时观察到已经编写的部分是否正确。最终完成这个shell程序的编写。 3)用shell程序提供的跟踪功能进行调试 shell程序可以使用 -v -x 选项对shell程序进行跟踪 -v:当读入shell输入行时把它们显示出来,完成详细跟踪。Shell程序在完成这段程序执行时首先逐行读入执行的命令,并在标准输出上显示该命令要执行的实际内容,然后执行该命令。如果没有语法错误,执行将一直进行下去直到完成shell的执行。 -x:执行命令前先把命令和它们的参数显示出来

3.9 Shell程序调试 假设有这么一个简单的shell,叫test1.sh date echo $PATH 我们用-v参数来调试, 执行sh -v test1.sh那么输出就应该是: Mon Sep 8 9:55:01 Linux9 2003 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 Linux9 2003 +echo /usr/bin:/usr/ucb/bin:/home/user1 /usr/bin:/usr/ucb/bin:/home/user1 date这一行没有参数,所以只显示命令 echo这一行有参数$path,被直接替换成了参数的值。

3.9 Shell程序调试 在调试一个比较大的shell时,没有必要对整个shell程序都进行跟踪,可以只对其中较为负责的部分进行跟踪,这时可以通过 set –v ……… set +v或者set –x …………set +x来把需要跟踪的部分包含进来。

3.10 Shell编程示例 1.使用for循环语句编写Bshell程序,完成显示用户注册目录下a_sub, b_sub子目录下的所有C程序源文件和目标文件的列表

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

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

3.10 Shell编程示例 2.连续输入若干个名字到文件file.names中保留 read 当Bsh遇到一个read语句时,在标准输入文件中读取数据直到一个换行符。此时Shell在解释输入行时,不进行文件名或变量的替换,只是简单地删除多余的空格。然后Shell将输入行的第一个字的内容给变量1,第二个给变量2,直到所有变量都赋上值或是输入行为空。若输入行中字的个数超过变量个数,Shell将把输入行中剩余的所有字的内容都赋给最后一个变量。当变量个数多于输入行字的个数时候,多于的变量将赋一个空值。输入行的每一个字是由空格分隔的一个字母和数字组成的字符串。可以通过重定向的方式从文件中读字符串。

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

3.10 Shell编程示例 3. 持续检测文件abc.txt是否存在

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 !"

3.10 Shell编程示例 4. 统计文件file的行数

3.10 Shell编程示例 count=0 while read LINE do count=`expr $count + 1` done < file echo $count 或者 cat file | wc -l

3.10 Shell编程示例 5. 编写shell程序files.sh实现如下功能:从命令行输入1到3个文件名,如果只输入一个文件名,则从键盘录入信息,保存到该文件中;如果输入两个文件名,则先显示两个文件的内容,再将文件1的内容追加到文件2的末尾;如果输入3个文件名,则将文件1和文件2的内容合并覆盖到文件3上。

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

3.10 Shell编程示例 6.为了便于系统管理员对磁盘分配的管理,请编写一段shell程序,当文件系统/home的占用空间量改变时,给出相应的信息提示。要求/home占用量在系统磁盘中为: 1)小于50%时,提示“用户系统文件磁盘使用负荷量小”。 2)大于50%,小于90%时,提示“用户文件系统磁盘使用负荷量正常” 3)大于90%时,提示“用户文件系统磁盘使用负荷量偏大”。

3.10 Shell编程示例 bc 一个简单的计算器。bc是一个支持交互的表达式计算的语言,其格式类似于C语言 命令行 echo 1+33*3 | bc 也能计算出1+33×3=100。 scale n 计算的精度 du 显示文件或目录所占的磁盘空间 -s 只显示设定文件目录的空间总量 -r 如果文件不能读取,则显示出提示信息 -a 可以接收多个文件,并一一显示所占的磁盘空间

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 ---"

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

3.10 Shell编程示例 7. 编写一个shell程序:根据从键盘输入的学生成绩,显示相应的成绩标准。

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

3.10 Shell编程示例 8. 假设文件score.txt中保存了三个班级的学生成绩,编写一段shell程序来计算3个班级的学生数目和平均成绩。

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

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

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 " 1 $NUMBER1 $SCORE1" echo " 2 $NUMBER2 $SCORE2" echo " 3 $NUMBER3 $SCORE3" IFS=$SAVED_IFS  

3.10 Shell编程示例 9.编写一段Shell程序完成:根据从键盘输入的学生学号,到成绩表文件中查找对应的成绩,并进行显示。成绩表的定义如下 score.dat 001|94 003|93 … ... 123|88

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

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的内容发生改变

3.11 用户工作环境设置 Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

3.11 用户工作环境设置 这些变量是用户在登录时进行赋值的,由shell统一维护,在用户注销时自动撤销。这些变量大部分是用户的基本的永久性变量,在用户工作时是不变的。但也有一部分变量是为了特殊目的而设定的,这些变量对用户有很大的针对性,同时也为用户提供了一定的自由度,因此它们允许用户根据自己的需要自行修改和调整。 Dos用户通常都知道,在系统启动时会自动执行启动盘根目录下的autoexec.bat文件(如果有这个文件)。这个文件可以完成PATH, PROMPT等环境变量的设置。同样的,UNIX系统下也有这种文件,而且通常不止一个,而是成一组的好几个文件。当然,根据用户设置的登录后使用的shell类型的不同,这些文件也有所不同。如果使用bsh,一般会有.bsh_profile, .bshrc, .bsh_logout等文件,如果是cshell,会有.cshrc这个文件,但是作用基本是相同的,都是设定用户缺省的环境变量。这些文件中的内容用户可以根据需要进行修改,以设成自己需要的内容。

3.11 用户工作环境设置 2)Bshell的环境变量 b shell是使用最广泛的UNIX系统,我们可以了解一下bshell的环境变量的设置。 在用户目录下有.bash_profile, .bashrc, .bash_logout三个和环境变量相关的文件,其中.bash_profile就相当于dos下面的autoexec.bat,我们来看看一个典型的.bash_profile的内容:

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

3.11 用户工作环境设置 它在执行的时候会调用.bshrc, 内容如下: # .bshrc   # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi

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=‘> ’   #附属提示符,默认是“>”

3.11 用户工作环境设置 LOGNAME=‘test’ #当前用户的登录名 _='clear' COLORS='/etc/DIR_COLORS' TERM='ansi' PPID='3296' PATH='/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin' REMOTEHOST='202.103.65.22' LANG=‘en_US.UTF-8’    #和语言相关的环境变量 HISTSIZE=‘1000’     #保存历史命令记录的条数 SHELL=‘/bin/bsh’    #当前用户用的是哪种Shell PWD='/home/test/t‘ 其他的shell如Cshell,Kshell均是大同小异

3.11 用户工作环境设置 相关文件 /etc/profile /home/liheng**/.bash_profile /home/liheng**/.bashrc /home/liheng**/.bash_logout 在这里修改的内容是对登录用户起作用的

作业 1、完成实验二,上机 2、查看文件 /etc/profile /home/liheng**/.bash_profile /home/liheng**/.bashrc /home/liheng**/.bash_logout