第九章 b-shell 及编程

56
第第第 B-Shell 第第第

Upload: margo

Post on 25-Jan-2016

155 views

Category:

Documents


11 download

DESCRIPTION

第九章 B-Shell 及编程. 主要内容. 主要目的 编写 shell 脚本 程序 交互方式下 使用 shell 的流程 控制,编写复合命令 主要内容 元字符,如:引号 shell 的变量 替换,命令替换,文件名生成 shell 变量 流程控制 子程序. 主要特点. 主要特点 shell 编程风格和 C 语言等算法语言的区别 shell 是面向命令处理的语言,提供的流程控制结构通过对一些内部命令的解释实现 如同 C 语言设计思路一样, shell 本身设计得非常精炼,但是它提供了灵活的机制 shell 许多灵活的功能,通过 shell 替换实现 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第九章  B-Shell 及编程

第九章 B-Shell 及编程

Page 2: 第九章  B-Shell 及编程

第 6章 第 2页

主要内容 主要目的

编写 shell脚本程序交互方式下使用 shell的流程控制,编写复合命令

主要内容元字符,如:引号shell的变量替换,命令替换,文件名生成shell变量流程控制子程序

Page 3: 第九章  B-Shell 及编程

第 6章 第 3页

主要特点 主要特点

shell编程风格和 C语言等算法语言的区别shell是面向命令处理的语言,提供的流程控

制结构通过对一些内部命令的解释实现如同 C语言设计思路一样, shell本身设计得

非常精炼,但是它提供了灵活的机制shell许多灵活的功能,通过 shell替换实现例如:流程控制所需的条件判断,四则运算,都由 shell之外的命令完成

Page 4: 第九章  B-Shell 及编程

1 启动 B-shell

Page 5: 第九章  B-Shell 及编程

第 6章 第 5页

启动交互式 B-shell 启动方法

注册 shell键入 sh 命令进入了 B-shell

自动执行的批处理文件当 sh 作为注册 shell 被启动时,自动执行用户主目录

下的 .profile 文件中命令,记作 $HOME/.profile类似 umask 之类的命令,应当写在 .profile 文件中

Page 6: 第九章  B-Shell 及编程

第 6章 第 6页

sh 脚本的执行 编辑文件 lsdir( 格式为文本文件 )

# ! /bin/shif [ $# = 0 ]then dir=.else dir=$1fifind $dir -type d –print

执行这一脚本 (script) 文件的方法 : sh<lsdirsh lsdirchmod u+x lsdir; ./lsdir /bin三种方法均启动程序 /bin/sh ,生成新进程

Page 7: 第九章  B-Shell 及编程

2 重定向与管道

Page 8: 第九章  B-Shell 及编程

第 6章 第 8页

输入重定向 <filename

从文件 filename 中获取 stdin例如 : sort < telno.txt

<<word 从 shell 获取数据直到再次遇到定界符 wordcat << TOAST* Now : `date`* My Home Directory is $HOMETOAST执行结果* Now : Sat Jul 27 14:47:56 Beijing 2006* My Home Directory is /usr/jiang定界符所界定内容加工处理 ( 等同双引号处理 ):

变量替换,命令替换不执行文件名生成

Page 9: 第九章  B-Shell 及编程

第 6章 第 9页

输出重定向 > filename

将 stdout重定向到文件 filename

2> filename将文件句柄 2 重定向到文件 filename

2>&1将文件句柄 2 重定向到文件句柄 1 指向的文件

sh 允许对除 0 , 1 , 2 外其它文件句柄重定向

Page 10: 第九章  B-Shell 及编程

第 6章 第 10页

输出重定向 ( 例 1) ls -l > file.list

将命令 ls 标准输出 stdout定向到文件 file.list 中 cc try.c -o try 2> try.bugs

将 cc 命令的 stderr重定向到文件 try.bugs 中 try > try.out 2>try.err try 1> try.out 2>try.err

将 try 程序执行后的 stdout和 stderr分别重定向到不同的文件

Page 11: 第九章  B-Shell 及编程

第 6章 第 11页

管道 ls -l | grep '^d' 前一命令的 stdout作后一命令的 stdin cc try.c -o try 2>&1 | more 前一命令的 stdout+stderr作为下一命令的 stdin

Page 12: 第九章  B-Shell 及编程

3 变量

Page 13: 第九章  B-Shell 及编程

第 6章 第 13页

sh 变量 存储的内容

字符串 ( 对于数字串来说,不是二进制形式 )在执行过程中其内容可以被修改

变量名第一个字符必须为字母其余字符可以是字母,数字,下划线

Page 14: 第九章  B-Shell 及编程

第 6章 第 14页

变量的赋值和引用 简单赋值与引用

addr=20.1.1.254 echo $addr 注意:赋值作为单独一条命令,等号两侧不许多余空格引用 addr 变量 $addr , echo 执行前, sh 完成变量替

换 赋值时,等号右侧字符串中含有特殊字符,

unit=”Beiyou University”echo $unit

引用未定义变量,变量值为空字符串echo Connect to $proto Networkproto=TCP/IPecho Connect to $proto Network

Page 15: 第九章  B-Shell 及编程

第 6章 第 15页

命令 echo 语法与功能

echo arg1 arg2 arg3 ...打印各命令行参数,每两个间用一空格分开,最后打印换行符

不可打印字符 ( 转义 ) : Linux 需加选项 -e

Page 16: 第九章  B-Shell 及编程

第 6章 第 16页

read: 读用户的输入内部命令 read:变量取值的另外一种方

法从标准输入读入一行内容赋值给变量例:读取用户的输入,并使用输入的信息。

$ read name ccp.c$ echo $nameccp.c$ ls -l $name-rw-r--r-- 1 jiang usr 32394 May 27 10:10 ccp.c$

Page 17: 第九章  B-Shell 及编程

第 6章 第 17页

环境变量和局部变量 默认类型

所创建的 shell变量,默认为局部变量 内部命令 export

局部变量转换为环境变量,例如:export proto

局部变量和环境变量shell启动的子进程继承环境变量,不继承局部变量子进程对环境变量的修改,不影响父进程中同名变量

相关命令 set/env 内部命令 set列出当前所有变量及其值

包括环境变量和局部变量外部命令 /bin/env列出环境变量及其值

Page 18: 第九章  B-Shell 及编程

在 shell 中有几个内置的变量,在 shell 脚本文件中可以直接使用这些内置变量,而且不允许对这些变

量直接赋值,见表 6-1 。 表 6-1 B-shell 的内置变量

内置变量

内 置 变 量 含 义$? 最后一次执行的命令的返回码$$ shell 进程自己的 PID

$! shell 进程最近启动的后台进程的 PID

$# 命令行参数的个数(不包括脚本文件的名字在内)$0 脚本文件本身的名字$1 $2, … 第一个, 第二个,…,命令行参数"$*" "$1 $2 $3 $4..." ,将所有命令行参数组织成一个整体,作为一个“单词”

"$@" "$1" "$2" "$3"... ,将多个命令行参数看作是多个“单词” 

Page 19: 第九章  B-Shell 及编程

表 6-1 ,从 $# 到 "$@" 的最后几项,是与 shell 脚本文件启动时附带的命令行参数相关的,也叫“位置变量”。在 9 节,介绍了位置变量可以使用内部命令 set 和 shift 进行重新设置。

Page 20: 第九章  B-Shell 及编程

第 6章 第 20页

系统的环境变量 创建

登录后系统自动创建一些环境变量影响应用程序运行 HOME :用户主目录的路径名 PATH :命令查找路径

与 DOS 不同的是 ,它不首先搜索当前目录PATH=/bin:/usr/bin:/etcPATH=./:/bin:/usr/bin:/etc 先搜索当前目录PATH=/:bin/usr/bin:/etc:./ 后搜索当前目录

PS1 和 PS2 :主提示符和副提示符 sh副提示符:当一个命令在一行内输不完需几行输入一

个命令时,第 2 行及其它行用副提示符 TERM :终端类型

全屏幕操作的软件 ( 如 vi) ,使用它搜索终端库

Page 21: 第九章  B-Shell 及编程

6.4 替换

Page 22: 第九章  B-Shell 及编程

第 6章 第 22页

shell 替换 Shell 的替换工作 : 先替换命令行再执行命令

文件名生成变量替换命令替换

文件名生成遵循文件通配符规则,按照字典序排列如 : ls *.c 文件名替换后实际执行 ls a.c x.c

变量替换 ls $HOMEecho ”My home is $HOME, Terminal is $TERM”

Page 23: 第九章  B-Shell 及编程

第 6章 第 23页

shell 替换 : 命令替换 用反撇号

now=`date` 以命令 date 的 stdout 替换 `date`./arg `date`

实际执行./arg Sun Dec 4 14:54:38 Beijing 2006

frames=`expr 5 + 13`echo $frames18count=10count=`expr $Count + 1`echo $count11

Page 24: 第九章  B-Shell 及编程

第 6章 第 24页

shell 内部变量:位置参数 $0

脚本文件本身的名字 $1

1 号命令行参数 $#

命令行参数的个数 "$*"

”$1 $2 $3 $4 ...” "$@"

”$1” ”$2” ”$3” …

Page 25: 第九章  B-Shell 及编程

5 元字符

Page 26: 第九章  B-Shell 及编程

第 6章 第 26页

shell 元字符 (1) 空格 , 制表符

命令行参数的分隔符 回车

执行键入的命令 > < |

重定向与管道 ;

用于一行内输入多个命令 &

后台运行 $

引用 shell 变量

Page 27: 第九章  B-Shell 及编程

第 6章 第 27页

shell 的元字符 (2) `

反向单引号,用于命令替换 * [] ?

文件通配符 (echo "*" 与 echo * 不同) \

取消后继字符的特殊作用 (转义 )若后继字符为非特殊字符,则不起作用

( ) 用于定义 shell函数 ,以及定义命令表

分隔符( )><|;& 等除了它们自身的特殊含义外还同时起到

分隔符的作用 ( 同空格 )

Page 28: 第九章  B-Shell 及编程

第 6章 第 28页

转义符反斜线作转义符,取消其后元字符的特

殊作用如果反斜线加在非元字符前面,反斜线

跟没有一样

Page 29: 第九章  B-Shell 及编程

第 6章 第 29页

元字符:引号 双引号 "

除 $ 和 ` 外特殊字符的特殊含义被取消需要的转义 \“ \$ \` \\echo * 与  echo "*“

单引号 ' 对所括起的任何字符,不作特殊解释echo "My home dir is $HOME"echo 'My home dir is $HOME'

Page 30: 第九章  B-Shell 及编程

6 条件判断

Page 31: 第九章  B-Shell 及编程

第 6章 第 31页

条件 条件判定的依据

判定一条命令是否执行成功,判断方法 : 命令执行的返回码, 0:TRUE( 成功 ) ,非 0:FALSE(失败 )

$ ls -d xyzxyz$ echo $? $?上一命令的返回码, shell 自定义变量0$ ls -d xyz1xyz1: not found$ echo $?2

用管道线连接在一起的若干命令的执行返回码为最后一个命令执行的返回码

Page 32: 第九章  B-Shell 及编程

第 6章 第 32页

最简单的条件判断用 && 或 || 连结两个命令 cmd1 && cmd2

若 cmd1 执行成功 (返回码为 0)则执行 cmd2 ,否则不执行 cmd2

cmd1 || cmd2 cmd1 执行失败 (返回码不为 0)则执行 cmd2 ,否则

不执行 cmd2

$ ls -d xdir >/dev/null && echo FOUNDFOUND若没有目录 ydir

$ ls -d ydir >/dev/null 2>&1 ||echo No ydirNo ydir

Page 33: 第九章  B-Shell 及编程

第 6章 第 33页

命令 true 与 false /bin/true

返回码总为 0 /bin/false

返回码总不为 0 有的 shell 为了提高效率,将 true 和 false 设置

为内部命令

Page 34: 第九章  B-Shell 及编程

第 6章 第 34页

命令 test 与 [ 区别

命令 /usr/bin/[要求其最后一个命令行参数必须为 ]

除此之外 /usr/bin/[与 /usr/bin/test功能相同 Linux 中 /usr/bin/[ 是一个指向 test 的符号连接

注意:不要将方括号理解成一个词法符号举例

test -r /etc/motd [ -r /etc/motd ]

Page 35: 第九章  B-Shell 及编程

第 6章 第 35页

命令 test :文件特性检测 文件特性检测

-f 普通文件 -d 目录文件 -r 可读 -w 可写 -x 可执行 -s size>0

例test -r /etc/motd && echo readable[ -r /etc/motd ] && echo readable

Page 36: 第九章  B-Shell 及编程

第 6章 第 36页

命令 test :字符串和整数 字符串比较

-n str str 串长度大于 0 str1 = str2 str1与 str2 串相等 str1 != str2 str1 串与 str2 串不等

注意 : 等号和不等号两侧的空格不可少 [ -n "$a" ] || echo a=NULL 注意 :$a 的引号 test $# = 0 && echo "No argument"

整数的比较 -eq = -ne ≠ -gt > -ge ≥ -lt < -le ≤

例 : test `ls | wc -l` -ge 100 && echo "Too many files"

Page 37: 第九章  B-Shell 及编程

第 6章 第 37页

命令 test :逻辑运算逻辑运算

! NOT(非) -o OR (或)-a AND (与)

例 : [ ! -d $cmd -a -x $cmd ] && $cmd 注意:必需的空格不可省略

$ cat hereecho ”count=$#”[ $#=2 ] && echo Here$ ./here *.ccount=9Here

Page 38: 第九章  B-Shell 及编程

第 6章 第 38页

条件结构 if 语法

if condition

then list

elif condition

then list

else list

fi其中 if/then/elif/else/fi 为关键字 ( 内部命令 )当条件判断后需要两个或多个分支时, && 和 ||就

不够了,这时应当用 if 结构

Page 39: 第九章  B-Shell 及编程

第 6章 第 39页

条件结构 if :举例$ cat errmonitorLOGFILE=./errlogdate>>$LOGFILEif test -w errfilethen cat errfile>>$LOGFILE rm errfileelse echo ”No error”>>$LOGFILEfithen 行可和 cat 行合并成一行if 行不可以和 then 行直接合并成一行将两行合并 : 分号使得一行内可以输入多条命令

if test -r errfile; then

Page 40: 第九章  B-Shell 及编程

第 6章 第 40页

case 结构基于文件名匹配基础上的多条件分支,语法 :

case word in pattern1) list1;; pattern2) list2;; ...esacword与 pattern匹配:使用 shell的文件名匹配规则;; 是一个整体,不能在两分号间加空格,也不能用

两个连续的空行代替可以使用竖线表示多个模式word与多个模式匹配时,执行遇到的第一个命令表

Page 41: 第九章  B-Shell 及编程

第 6章 第 41页

case 结构:举例 语法

case "$1" inSTART|start) ... ( 一段程序 ) ;;STOP|stop) ... ( 一段程序 ) ;;*) echo "Usage: $0 [start|stop]" ;;esac

注意:本例中 case 句中 $1 要加上双引号

Page 42: 第九章  B-Shell 及编程

6.7 循环结构

Page 43: 第九章  B-Shell 及编程

第 6章 第 43页

while 结构 语法

while condition do list

done 例 1

while test -r lockfiledo sleep 5done

下例有错while test -r lockfile do sleep 5done

例 2while [ -r lockfile ]; do sleep 5;done

Page 44: 第九章  B-Shell 及编程

第 6章 第 44页

命令 expr :表达式计算 功能:求表达式的值

shell本身不提供数学运算和字符串运算的能力,这些运算借助命令 expr 完成

算数运算 + - * / % ()

注意应该转义的地方必须加反斜线转义应该有空格的地方不允许漏掉。

例 1: 求变量 a*(b+c)正确的写法为 expr $a \* \( $b + $c \)

Page 45: 第九章  B-Shell 及编程

第 6章 第 45页

命令 expr :算数运算 ( 例 )if [ $# = 0 ]then echo "Usage: $0 : <number>"else count=$1 while [ $count -gt 0 ] do count=`expr $count - 1` echo -e "$count \c" sleep 1 done fi

Page 46: 第九章  B-Shell 及编程

第 6章 第 46页

for 结构 语法 1

for name in word1 word2 ... do listdone

语法 2for name do listdone相当于for name in $1 $2 ... do listdone

Page 47: 第九章  B-Shell 及编程

第 6章 第 47页

for 结构:程序举例 2 例 2 :将命令行参数逆序显示出来

list=” ”for argdo list=”$arg $list”doneecho ”$list”

Page 48: 第九章  B-Shell 及编程

第 6章 第 48页

break 内部命令 break

循环结构 for/while 中使用,中止循环例 :将命令行参数逆序输出count=$#cmd=echowhile truedo cmd=”$cmd \$$count” count=`expr $count - 1` [ $count -eq 0 ] && breakdoneeval $cmd

Page 49: 第九章  B-Shell 及编程

第 6章 第 49页

continue 内部命令 continue

在循环结构 for/while 中使用,提前结束本轮循环例 :将命令行参数逆序输出count=$#cmd=echowhile truedo cmd=”$cmd \$$count” count=`expr $count - 1` [ $count -gt 0 ] && continue eval $cmd exit 0 done

内部命令 exit终止当前 shell进程

Page 50: 第九章  B-Shell 及编程

6.8 函数

Page 51: 第九章  B-Shell 及编程

第 6章 第 51页

shell 函数 语法

name() { list;} 参数

调用时函数名后附加上 0 到多个参数在函数体内部以 $1 , $2 , ...或 $* , $@方式引

用 返回值

函数体内用 return 使函数有返回码,返回码 0代表成功,非零表示失败

函数内部可以创建和修改变量,函数返回后其它程序访问

Page 52: 第九章  B-Shell 及编程

第 6章 第 52页

Shell 的注释 shell 中使用 # 号作注释

# 号出现在一个单词的首部,那么,从 # 号至行尾的所有字符被忽略

Page 53: 第九章  B-Shell 及编程

第 6章 第 53页

shell 函数举例get_val() # Usage: get_val 变量名 提示 默认值 取值表{ while true do echo -e "$2 [$3] : \c" ; read val [ "$val" = "" ] && val=$3 for i in $4 do [ "$val" = "$i" ] && break 2 done echo "**** Invalid choice $val, must be in $4" done eval "$1=$val" } # main() get_val INTR "Interrupt Number" 10 "5 10 11 12 14" get_val PORT "I/O Base Address" 800 "512 560 800" get_val BAUD "Baud Rate" 9600 "2400 9600 57600" echo "INTR=$INTR PORT=$PORT BAUD=$BAUD"

Page 54: 第九章  B-Shell 及编程

6.9 shell 开关和位置变量

Page 55: 第九章  B-Shell 及编程

第 6章 第 55页

shell 内部开关 shell 内部开关

-x 执行命令前打印出 shell 替换后的命令及参数,为区别于正常的 shell 输出,前面冠以 + 号

+x 取消上述设置-u 当引用一个未定义的变量时,产生一个错误+u 当引用一个未定义的变量时,认为是一个空串

Page 56: 第九章  B-Shell 及编程

第 6章 第 56页

shell 内部开关程序举例 例: cat chmod1

set -xecho "$*"for ido [ -f $i ] && { chmod a+r $i eoho "$i is readable" }done

内部开关的设置方法set -x也可以省略,使用命令 sh -x chmodl a*交互式 shell也可以使用 set -x/set +x使用 shell 的 -x选项对 shell 程序调试非常有用