Presentation is loading. Please wait.

Presentation is loading. Please wait.

第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本

Similar presentations


Presentation on theme: "第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本"— Presentation transcript:

1 第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本
文件; 2. 赋予shell文件执行权限 用chmod命令修改权限; 3. 执行shell文件 直接在命令行上调用shell程序.

2 实例: 1. 建立shell文件 (可用任何建立文本文件的方法): $ cat prog1 who | grep $1
2. 赋予执行权限: (初始文本文件无执行权限) $ chmod prog1 3. 执行该shell程序 $ prog1 student5 prog1: not found (shell在标准搜索目录中找不到prog1命令) 4. 指定路径或修改环境变量PATH后执行shell程序 $ ./prog1 student5 student5 tty06 Feb :12

3 shell 程序和语句 shell 程序由零至多条shell语句构成. shell语 句包括三大类: 功能性语句、结构性语句和说明性 语句.
说明性语句: 以#号开始到行尾的部分,不被解释执行 功能性语句: 任意的操作系统命令、shell内部命令、自编 程序、其它shell程序名等。 结构性语句: 条件测试语句、多路分支语句、循环语句、 循环控制语句等。

4 告诉OS用哪种类型的shell来解释执行该程序
说明性语句(注释行): 注释行可以出现在程序中的任何位置,既可以 单独占用一行, 也可以接在执行语句的后面. 以#号 开始到所在行的行尾部分,都不被解释执行. 例如: #! /bin/sh # # 本程序说明 command_1 command_ # command_2的语句说明 …… # 下面程序段的说明 command_m command_n # commandn_语句的说明 告诉OS用哪种类型的shell来解释执行该程序

5 几个常用的功能性语句(命令): read命令 read从标准输入读入一行, 并赋值给后面的变量, 其语法为: . read var
. read var1 var2 var3 把读入行中的第一个词(word)赋给var1, 第 二个词赋给var2, ……把其余所有的词赋给最后一 个变量. 如果执行read语句时标准输入无数据, 则程序 在此停留等侯, 直到数据的到来或被中止运行.

6 应用实例 # example1 for read echo "Input your name: \c" read username
echo "Your name is $username" #example2 for read echo "Input date with format yyyy mm dd: \c" read year month day echo "Today is $year/$month/$day, right?" echo "Press any key to confirm and continue\c" read answer echo "I know the date, bye!"

7 expr 命令 算术运算命令expr主要用于进行简单的整数运算,包 括加(+)、减(-)、乘(\*)、整除(/)和求模(%)等操 作。例如:
27 $ expr / 2 -1 $ expr % 4 1 $ num=9 $ sum=`expr $num \* 6 ` $ echo $sum 54 反斜线去掉*号的元字符含义 反撇号引用命令的运行结果

8 tput 命令 选项 功 能 tput命令主要用于设置终端工作模式, 或读出终端控制
字符. tput命令与终端控制代码数据库terminfo相连, 根据 shell环境变量TERM的值, 读出这种终端的指定功能控制代 码. 常用的终端功能控制如下表: 选项 功 能 bel 终端响铃 el 光标位置到行末清字符 blink 闪烁显示 smso 启动突出显示模式 bold 粗体字显示 smul 启动下划线模式 clear 清屏 rmso 结束突出显示模式 cup r c 光标移到 r 行 c 列 rmul 结束下划线模式 dim 显示变暗 rev 反白显示 ed 光标位置到屏幕底清屏 sgr0 关闭所有属性

9 应用实例一: # # program1 for tput tput clear tput cup 11 30 tput rev
echo "Hello, everybody!" tput sgr0 tput cup 该程序先清屏, 并在屏幕中央位置(11行23列)用反极性 显示字符串"Hello, everybody!", 恢复正常显示极性后光标 停留在屏幕左下角.

10 在$bell和$s_uline之间的空格将同样在屏幕上显示, 使Computer Department的实际位置向右移动一格
应用实例二: # # program2 for tput bell=`tput bel` s_uline=`tput smul` e_uline=`tput rmul` tput clear tput cup echo $bell $s_uline echo "Computer Department" echo $e_uline 功能: 响一声铃后, 在清空的屏幕中央以下划线模式显示字 符串"Computer Department" 注意 在$bell和$s_uline之间的空格将同样在屏幕上显示, 使Computer Department的实际位置向右移动一格

11 结构性语句: 结构性语句主要根据程序的运行状态、 输入数据、变量的取值、控制信号以及运行 时间等因素来控制程序的运行流程。主要包
括:条件测试语句(两路分支)、多路分支 语句、循环语句、循环控制语句和后台执行 语句等。 无任何结构性语句的shell程序是一种特 例。

12 一. 条件语句 if…then…fi 语法结构: if 表达式 then 命令表 fi 如果表达式为真, 则执行命令表中的命令; 否则退
出if语句, 即执行fi后面的语句. if和fi是条件语句的语句括号, 必须成对使用; 命令表中的命令可以是一条, 也可以是若干条.

13 shell程序prog2, 测试命令行参数是否为已存在 的文件或目录. 用法为: prog2 file 内容如下:
例子: shell程序prog2, 测试命令行参数是否为已存在 的文件或目录. 用法为: prog2 file 内容如下: #The statement of if…then…fi (注释语句) if [ -f $1 ] (测试参数是否为文件) then echo "File $1 exists" (引用变量值) fi if [ -d $HOME/$1 ] (测试参数是否为目录) echo "File $1 is a directory" (引用变量值)

14 执行prog2程序: $ prog2 prog1 File prog1 exists
$ prog2 backup File backup is directory $0为prog2; $1为backup,是一个已存在的目录. 如果不带参数, 或大于一个参数运行prog2, 例如: $ prog (或 $ prog2 file1 file2) 将会出现什么结果?

15 二. 条件语句 if…then…else…fi
语法结构为: if 表达式 then 命令表1 else 命令表2 fi 如果表达式为真, 则执行命令表1中的命令, 退出if 语句; 否则执行命令表2中的语句, 退出if语句. 注意: 无论表达式是否为真, 都有语句要执行.

16 (如果没有exit语句,程序的执行结果是什么?)
例子: shell程序prog3, 用法为: prog3 file 内容如下: #The statement of if…then…else…fi if [ -d $1 ] then echo "$1 is a directory" exit (退出当前的shell程序) else if [ -f $1 ] echo "$1 is a common file" echo "unknown" fi (如果没有exit语句,程序的执行结果是什么?)

17 运行prog3程序: $ prog3 backup backup is a directory $ prog3 prog1
prog1 is a common file $ prog3 abc unknown prog3是对prog2的优化, 逻辑结构更加清晰合理! prog2的主要缺点是什么?

18 三. 测试语句 test test语句可测试三种对象: 字符串 整数 文件属性 每种测试对象都有若干测试操作符, 参见表8.14 例如:
字符串 整数 文件属性 每种测试对象都有若干测试操作符, 参见表8.14 例如: test "$answer" = "yes" 变量answer的值是否为字符串yes test $num –eq 18 变量num的值是否为整数18 test -d tmp 测试tmp是否为一个目录名

19 test命令的应用: test命令测试的条件成立时, 命令返回值为真(0) 否则返回值为假(非0). 用法一.
liudi: test命令的应用: test命令测试的条件成立时, 命令返回值为真(0) 否则返回值为假(非0). 用法一. test $name -eq $1 echo $? 用法二. if test -f $filename then …… fi 通常简写为: if [ -f $filename ] 用方括号替代test语句 至少一个空格 至少一个空格

20 命令表以单独的双分号行结束,退出case语句
四. 多路分支语句 case…esac 多路分支语句case用于多重条件测试, 语法结构 清晰自然. 其语法结构为: case 字符串变量 in 模式1) 命令表1 ;; 模式2) 命令表2 …… 模式n) 命令表n esac case语句只能检测字符串变量 各模式中可用文件名元字符,以右括号结束 命令表以单独的双分号行结束,退出case语句 模式 n常写为字符* 表示所有其它模式 最后一个双分号行可以省略

21 实例. 程序prog4检查用户输入的文件名, 用法为:
prog4 string_name # The statement of case…esac if [ $# -eq 0 ] then echo "No argument is declared" exit fi case $1 in file1) echo "User selects file1" ;; file2) echo "User selects file2" *) echo "You must select either file1 or file2!" esac

22 五. 循环语句 for…do…done 当循环次数已知或确定时, 使用for循环语句来多次执行
为: for 变量名 in 单词表 do 命令表 done 变量依次取单词表中的各个单词, 每取一次单词, 就执行一 次循环体中的命令. 循环次数由单词表中的单词数确定. 命 令表中的命令可以是一条, 也可以是由分号或换行符分开的 多条. 如果单词表是命令行上的所有位置参数时, 可以在for 语句中省略 "in 单词表" 部分.

23 flist的值是ls的执行结果即当前目录下的文件名
实例. 包含for语句的程序prog5拷贝当前目录下的所有文 件到backup子目录下. 使用语法及程序为: prog5 [filename] # The statement of for…do…done If [ ! -d $HOME/backup ] then mkdir $HOME/backup fi flist=`ls` for file in $flist do if [ $# = 1 ] if [ $1 = $file ] echo "$file found" ; exit else cp $file $HOME/backup echo "$file copied" done echo '***Back up completed***' flist的值是ls的执行结果即当前目录下的文件名 命令行上有一个参数时 命令行上不带参数时

24 六. 循环语句 while…do…done 语法结构为: while 命令或表达式 do 命令表 done
就执行一次循环体中的命令,然后再测试该命令或表达式 的值,执行循环体,直到该命令或表达式为假时退出循环。 while语句的退出状态为命令表中被执行的最后一条命 令的退出状态。

25 建立以file开头, 变量i的值结尾的空文件名. 参见命令
实例. 创建文件程序prog6, 用法为: prog6 file [number] # The statement for while if [ $# = 2 ] then loop=$2 else loop=5 fi i=1 while [ $i -eq $loop ] do >$1$i i=`expr $i + 1` done 根据命令行参数的个数确定循环的次数 建立以file开头, 变量i的值结尾的空文件名. 参见命令 cmd > file

26 七. 循环语句 until…do…done 语法结构为: until 命令或表达式 do 命令表 done
until循环与while循环的功能相似, 所不同的是只有 当测试的命令或表达式的值是假时, 才执行循环体 中的命令表, 否则退出循环. 这一点与while命令正 好相反.

27 八. 循环控制语句 break 和 continue
一层, break n 则跳出n层; continue语句则马上转 到最近一层循环语句的下一轮循环上, continue n 则转到最近n层循环语句的下一轮循环上. 实例. 程序prog7的用法为: prog7 整数 整数 整数 … 参数个数不确定, 范围为1~10个, 每个参数都是正整 数.

28 if [ $# = 0 ] then echo "Numeric arguments required" exit fi if [ $# -gt ] echo "Only ten arguments allowed" for number do count=`expr $number % 2` if [ $count -eq 1 ] continue else output="$output $number" done echo "Even numbers: $output " 取所有位置参数 用2求模, count的值只能是0或1 是奇数 偶数放到偶数队列中

29 实例. 包含while、until和break语句的prog8 程序.
while true do echo level1 until false echo level2 echo level3 break done while语句后的表达式为true(真), until语句后的表达式为 false(假), 循环条件永远成立, 因此是无限循环. 死循环程序, 只能由人工中断 改为continue 3 开始最外层循环 如果改为break 3 跳出最外层循环

30 在shell程序中, 常常把完成固定功能、且多次使
用的一组命令(语句)封装在一个函数里,每当要 使用该功能时只需调用该函数名即可。 函数在调用前必须先定义,即在顺序上函数说 明必须放在调用程序的前面。 调用程序可传递参数给函数, 函数可用return语 句把运行结果返回给调用程序. 函数只在当前shell中起作用, 不能输出到子shell 中.

31 函数的所有标准输出都传递给了主程序的变量 函数的返回值隐含在变量中, 由主程序使用该变量的值
函数格式: function_name ( ) { command1 …… commandn } 函数调用格式: value_name=`function_name [arg1 arg2 … ]` 或者: function_name [arg1 arg2 … ] echo $value_name 函数的所有标准输出都传递给了主程序的变量 函数的返回值隐含在变量中, 由主程序使用该变量的值

32 实例: check_user( ) #查找已登录的指定用户 { user=`ps –e | grep $1` if [ -n $user ]
then return #找到指定用户 else return #未找到指定用户 fi } while true # MAIN, Main, main: program begin here do echo "Input username: \c" read uname check_user uname # 调用函数, 并传递参数uname if [ $? –eq 1 ] # $?为函数返回值 then echo "user $uname online" else echo "user $uname offline" done


Download ppt "第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本"

Similar presentations


Ads by Google