9 Shell 编程.pdf
3 Sept.2008 Neusoft ConfidentialLinux应用程序开发环境应用程序开发环境第九章:第九章:Shell 编程编程目标:目标:本章使学员掌握本章使学员掌握Linux操作系统下操作系统下Shell编程:编程:1)了解)了解Linux各各Shell环境环境2)熟悉)熟悉Shell下可用资源下可用资源3)掌握)掌握Shell编程语法编程语法时间:时间:5学时教学方法:讲授学时教学方法:讲授PPT+上机操作上机操作+实例演示实例演示什么是什么是什么是什么是shellshellshell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。Shell、用户及linux系统内核之间关系为什么要使用为什么要使用为什么要使用为什么要使用shellshell1.1.功能强大功能强大所有的UNIX命令和工具再加上公共程序,对于shell 脚本来说,都是可调用的。有强大的字符处理公共程序。2.2.灵活方便灵活方便具有控制流结构(if,else,for等)本地变量及环境变量3.3.不需要编译不需要编译Shell Shell 脚本对于管理系统任务和其它的重复工作的例程来说脚本对于管理系统任务和其它的重复工作的例程来说,表表现的非常好现的非常好linux的启动加载内核执行init程序执行/etc/rc.d/rc.sysinit#由init执行的第一个脚本执行/etc/rc.d/rc#根据inittab中的运行模式启动执行/etc/rc.d/rc.local执行/sbin/mingetty#等待用户登录登录后启动/etc/profile/etc/bashrc.提示提示可以通过修改/etc/inittab文件改变linux运行模式Shell的功能和特点1.命令行解释2.使用保留字3.使用Shell元字符(通配符)4.可处理程序命令5.使用输入输出重定向和管道6.维护一些变量7.结构流控制命令行解释命令行解释在一个最简单的例子中,一个shell 脚本其实就是将一堆系统命令列在一个文件中。它的最基本的用处就是,在你每次输入这些特定顺序的命令时可以少敲一些字。例:#!/bin/bashcd/home/ap/odstar cvf bak.tarmv bak.tar./tmp要注意,在脚本的开头要使用“#!”,这意味着告诉你的系统这个文件的执行需要指定一个解释器。在#!之后接着是一个路径名.这个路径名指定了一个解释脚本中命令的程序,这个程序可以是shell,程序语言或者是任意一个通用程序.这个指定的程序从头开始解释并且执行脚本中的命令如:#!/bin/sh#!/bin/bash#!/usr/bin/perlShell的保留字Shell有一些具有特殊意义的字,例如在Shell脚本中,do,done,for等字用来控制循环操作,if,then等控制条件操作。保留字随Shell环境的不同而不同。使用使用Shell元字符元字符(通配符通配符)bash 支持三种通配符:*匹配任何字符和任何数目的字符?匹配任何单字符.匹配任何包含在括号里的单字符*通配符的使用有些象命令补齐。例如,假设当前目录包含以下文件:/usr/src/linux-2.4.34 如果你想进入 linux-2.4.34 目录,假设src目录里只有唯一一个以l字母开头的目录,你可以利用通配符*来进入#cd l*通配符?除了只能匹配单个字符外,其他功能都与通配符*相同例子:假设目录里有 name1.doc name2.doc name3.doc等文件。如果你只想列出以name开头的doc文件,你可以执行:#ls name?.doc通配符.能匹配括号中给出的字符或字符范围例子:假设目录里有 name1.doc name2.doc name3.doc等文件。如果你只想列出以name开头的doc文件,你可以执行:#ls name1-3.doc 或者#ls name123.doc Shell中的命令别名中的命令别名命令别名通常是其他命令的缩写,用来减少键盘输入例子:cd/usr/X11/lib/X11/fvwm/sample-configs 定义:alias myconfig=cd/usr/X11/lib/X11/fvwm/sample-configs取消定义:unalias myconfig(1)shell脚本的建立Shell程序可以存放在文件中,这种被shell解释执行的命令文件称为shell脚本。Shell脚本程序与DOS/Windows系统的.bat批处理文件极为相似,但功能远远超过.bat批处理文件。shell脚本可以包含任意从键盘键入的Linux命令。建立shell脚本的步骤与建立普通文本文件的方式相同,利用编辑器(如vi)进行程序录入和编辑加工。shell脚本的建立和执行脚本的建立和执行一个简单的脚本一个简单的脚本脚本应以#!/bin/bash 开始,exit为结束,通过第一条语句,可以使系统知道使用哪个shell程序对脚本进行解释执行shell脚本的方式基本上有下述两种。1)以脚本名作为参数。其一般形式:#bash 脚本名例:执行shell脚本的方式#bash ex22)将shell脚本的权限设置为可执行,然后在提示符下直接执行它。通常,用户是不能直接执行由正文编辑器(如vi)建立的shell脚本的,因为直接编辑生成的脚本文件没有“执行”权限。如果要把shell脚本直接当作命令执行,就需要利用命令chmod将它置为有“执行”权限。例如,$chmod a+x ex2 就把shell脚本“ex2”设置为对所有用户都有“执行”权限。然后,在提示符后输入脚本名“ex2”就可直接执行该文件。例如#chmod a+x ex2#./ex2Shell中特殊字符中特殊字符#注释语句除第一行#!外;命令分隔符,用来在一行中执行多个命令;case语句中终止执行功能“双引号内的字符内容不完全输出 单引号内的字符内容完全输出转义符/命令替换:空命令,等价于NOP,bash内建命令作用相同于真值$显示变量的值()对一串命令重新开子shell执行,最后一个命令不用分号对一串命令在当前shell执行,最后一个命令要用分号 重定向符,将输出内容输入到文件中 重定向符,将输出内容添加到文件中|强制重定向,覆盖文件Shell的运算符的运算符=等于!=不等于-eq等于-ne 不等于-lt小于-gt大于-le 小于或等于-ge大于或等于-z 等于零或字符串为null-n 字符串不为nullShell中的变量中的变量Shell程序中也采用变量,用来存放字符串。Shell变量比C语言中的变量简单得多,没有众多存储类及类型的限制,也不需要预先定义,然后才能赋值,可以在使用时“现定义、现赋值”。Shell有两类变量:环境变量和临时变量。环境变量是永久性变量,其值不会随shell脚本执行结束而消失。而临时变量是在shell程序内部定义的,其使用范围仅限于定义它的程序,离开了本程序就不能再用它,而且当程序执行完毕,它的值也就不存在了。1.变量名用户定义的变量是最普通的shell变量。变量名是以字母或下划线打头的字母、数字和下线线序列,并且大小写字母意义不同。例如,dir与Dir是本身不同的变量。这与C语言中标识符的定义相同。变量名的长度不受限制。2变量赋值定义变量并赋值的一般形式:变量名=字符串例如,myfile=/usr/meng/ff/m1.c中的“myfile”是变量名,“=”是赋值号,字符串/usr/meng/ff/m1.c是赋予变量myfile的值。注意:在赋值语句中,赋值号“=”的两边没有空格,否则在执行时会引起错误。变量的值可以改变,只需利用赋值语句重新给它赋值。例如:myfile=/usr/liu/ex1此时,变量myfile的值就是/usr/liu/ex1。3引用变量值在程序中使用变量的值时,要在变量名前面加上一个符号“$”。这个符号告诉shell,要取出其后变量的值。例如,用echo命令显示变量值。#dir=/usr/meng/ff#echo$dir/usr/meng/ff(显示结果)#echo dirdir在用户登录过程中系统要做的第一件事就是建立用户环境,就是Shell 下的控制及设置,包括文件搜索路径、用户目录和系统提示符等。Linux(Shell)环境由许多变量和这些变量的值组成,通过设置这些环境变量来控制用户环境。查看所有环境变量#envShell环境变量环境变量1)HOME:用户主目录的全路径名。主目录是开始工作的位置,默认情况下,普通用户的主目录为/home/用户名,root用户的主目录为/root。不管你当前路径在哪里,都可以通过命令cd$HOME返回到主目录(最简单的是cd,然后直接回车或cd,然后回车)。常用的环境变量2)LOGNAME:用户名(注册名),由Linux自动设置,系统通过与LOGNAME变量确认文件的所有者,有权执行某个命令等。3)PATH:Shell从中查找命令的目录列表,它是一个非常重要的Shell变量。PATH变量包含有带冒号分界符的字符串,这些字符串指向含有你所使用命令的目录。PATH变量中的字符串顺序决定了先从哪个目录查找。PATH环境变量的功能和用法与DOS/Windows系统的几乎完全相同。例如PATH=$PATH:$HOME/bin4)PS1:Shell的主提示符,既在Shell准备接受命令时显示的字符串,PS1定义你的主提示符是怎样构成的。一般设为PS1=uh W$“意思是:用户名主机名 当前目录。5)PWD:你当前的工作目录的路径,它指出目前你在什么位置。6)SHELL:你当前使用的Shell和Shell放在什么位置。例如,查看用户登录系统时默认使用的Shell。最简单的方式是执行echo命令,查询系统环境变量的值。方法如下:$echo$SHELL/bin/bash4删除环境变量设置$unset NAME(如果NAME为一个环境变量)5设置环境变量的文件使用Bash Shell时,有以下几个文件和用户的作业环境有关:1)/etc/profile2)/etc/bashrc3)/etc/inputrc4)$HOME/.bash_profile5)$HOME/.bashrc6)$HOME/.inputrc7)$HOME/.bash_login定义与获取数组变量的值定义与获取数组变量的值定义数组ARRAY=(1 2 3 4 5 6)获取数组元素的值#echo$ARRAY1#echo$ARRAY01#echo$ARRAY1 2 3 4 5 6#array=($ARRAY)#echo$#array6直接输出的是数组的第一个元素直接输出的是数组的第一个元素用下标的方式访问数组元素用下标的方式访问数组元素输出这个数组输出这个数组输出数组元素个数输出数组元素个数数组操作数组操作生成输出信息echo&printf使用echo生成简单的输出信息:#echo Welcome to Red Hat Liunx!#echo-n Welcome to Red Hat Liunx!#echo e ttWelcome to Red Hat Liunx!使用printf生成格式化的输出信息:语法和C语言类似:#!/bin/bashNAME=bibbyprintf Name is%sn$NAME获取用户输入获取用户输入read和C语言中的scanf()类似:#!/bin/bashread ANSWERecho$ANSWERread p Type your name here:NAMEecho$NAME 退出与退出状态值退出与退出状态值 每个命令在退出时都会返回一个退出状态值正常退出,返回0;异常退出,返回非0(大于0小于等于255的整数)退出状态值保存在特殊变量$?中#ls#echo$?0#ls/tmp/non-exist-filels:/tmp/non-exist-file:No such file or directory#echo$?2命令替换命令替换将命令的结果直接赋值给变量。两种写法:#DATE=/bin/date+%Y#echo$DATE2007#DATE=$(/bin/date+%Y)#echo$DATE2007实验实验题目:创建一个shell脚本,用于备份整个/etc目录要求:?使用tar命令对/etc目录进行压缩和备份?备份文件保存在/root/backup目录下以月份命令的目录中格式为/root/backup/2009.11/?自动检测目录是否存在?备份文件的名称必须包含日期,格式为:etc-2007.xx.xx.tar.bz2;实验实验:代码示例代码示例#!/bin/bashARCHIVE_ROOTDIR=“/root/backup/”ARCHIVEDIR=“$ARCHIVE_BOOTDIR/$(/bin/date+%Y.%m)”BACKUPFILE=“$ARCHIVEDIR/etc-$(/bin/date+%Y.%m.%d).tar.bz2”#check backup directory.-d“$ARCHIVEDIR”|mkdir p$ARCHIVEDIRtar cjf$BACKUPFILE/etctest(判断判断)test可用于:文件状态判断;字符串比较;数字比较;test命令的语法#test condition#condition 中括号、参数之间必须有一个空格see also:#man testtest(判断判断):文件状态判断文件状态判断(cont)#-e/etc/passwd#test-e/etc/passwd#echo$?0#-x/etc/passwd#echo$?1-e 文件存在-f 文件是一个普通文件,不是目录或者设备文件-s 文件长度不为0-d 文件是个目录-b 文件是个块设备(磁盘、cdrom等)-c 文件是个字符设备-L 文件是个符号链接-r 文件具有只读权限-w 文件具有写权限-x 文件具有可执行权限test(判断):字符串比较#NAME=yang#$NAME=yang#$NAME=yang#echo$?0#NAME=yang#$NAME=bbbb#echo$?1参数含义=或或=两个字符串相等!=两个字符串不等-z空字符串-n非空字符串if语句if 条件判断一&(|)条件判断二thencommand1 elif 条件判断三&(|)条件判断四thencommand2elsecommand3fi#!/bin/bashread p Enter your name here:NAMEif$NAME=root thenecho You are root.elif$NAME=student thenecho You are student.elseecho I do not know who you are.fi1 if与条件中间一定不要漏写空格2 elif不要写成elseif3 不要漏写fi注!case语句case var inpattern_1)command_1;pattern_2)command_2;pattern_3|pattern_4)command3;*)command_4;esac1;不要忘写,如果不写,将继续执行下一个case。2 必须要有默认选项,类似于C的default3 不要漏写esac注!case例1#!/usr/bin/bashread p Enter a number from 1 to 5:ANSWERcase$ANSWER in1)echo You select 1.;2)echo You select 2.;3)echo You select 3.;4|5)echo You select 4 or 5.;*)echo Please enter a number from 1 to 5.;esacfor循环for VAR in VALUE_LISTdocommand_listdonefor VAR in VALUE_LIST;docommand_listdone1VAR是一个变量。2 VALUE_LIST是VAR可取的值,通常是一个数组。3 VAR依次取得VALUE_LIST中的值for循环例例:”for”for(i=0;i100;i+)doecho$idone例:”for in”LIST=“Tomy Jony Mary Geoge”for i in$LISTdoecho$idonewhile循环&until循环while循环用于不断执行一系列命令,也用于从输入文件中读取数据;while commanddocommand_listdoneuntil循环执行一系列命令直到条件为真时停止until循环与while循环在处理方式上正好相反until commanddocommand_listdonewhile&until 例echo“Press y/Y to stop”until “$yn”=“y”|“$yn”=“Y”doread yndoneecho“Stop here”例while:#!/bin/bashCOUNTER=0while$COUNTER-lt 5;doCOUNTER=$(COUNTER+1)echo$COUNTERdone例until:break&continuebreak命令允许跳出循环或case语句如果是在一个嵌入循环里,可以指定跳出的循环个数。例如,如果在两层循环内,用 break 2 刚好跳出整个循环。shell中的break与C语言的break相似continue 只是跳过本次循环继续运行,但不会跳出整个循环。shell中的continue与C语言的continue相似9.6 Shell编程编程脚本参数指定:#myscript opt1 opt2 opt3 opt4$0$1$2$3$4特殊参数$0 这个程式的执行名字$n 这个程式的第n个参数值,n=1.9$*这个程式的所有参数$#这个程式的参数个数$这个程式的PID$!执行上一个指令的PID$?执行上一个指令的返回值显示显示shell脚本名称及执行参数脚本名称及执行参数-n 字符串不为字符串不为null-lt 小于小于判断是否相等的四种方法判断是否相等的四种方法四个判断方法效果一样-z 等于零或字符串为等于零或字符串为null创建多个文件创建多个文件检查文件是否存在检查文件是否存在确认文件存在,然后查看或执行显示文件信息显示文件信息awk命令用于格式化输出一行字符串whatis 命令用于显示某个命令的简介9.6 Shell编程编程关于date命令与临时文件相关的脚本判断是否是判断是否是root权限权限创建创建ramdiskdd 这个指令是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换这个指令是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换if 指的是要被转换的输入档案格式指的是要被转换的输入档案格式/dev/zero 可以由可以由 man zero 来查看内容;来查看内容;of 指的是输出的档案,我们将之输出到指的是输出的档案,我们将之输出到/dev/ram0 这个档案;这个档案;bs 指的是一个扇区占用多少字节;指的是一个扇区占用多少字节;count 指的是要使用多少个指的是要使用多少个 bs,所以最后的容量为,所以最后的容量为 bs*count=1k*2000 2MBmke2fs 将设备格式化为将设备格式化为ext2格式格式谢谢!谢谢!Copyright 2008 版权所有 东软集团