文章目录
1. 软件测试基本理论
1.1 软件生命周期
- 问题的定义及规划
此阶段是软件开发方与需求方共同讨论,主要确定软件的开发目标及其可行性。 - 需求分析
在确定软件开发可行的情况下,对软件需要实现的各个功能进行详细分析。需求分析阶段是一个很重要的阶段,这一阶段做得好,将为整个软件开发项目的成功打下良好的基础。“唯一不变的是变化本身。”,同样需求也是在整个软件开发过程中不断变化和深入的,因此我们必须制定需求变更计划来应付这种变化,以保护整个项目的顺利进行。 - 软件设计
此阶段主要根据需求分析的结果,对整个软件系统进行设计,如系统框架设计,数据库设计等等。软件设计一般分为总体设计和详细设计。好的软件设计将为软件程序编写打下良好的基础。 - 程序编码
此阶段是将软件设计的结果转换成计算机可运行的程序代码。在程序编码中必须要制定统一,符合标准的编写规范。以保证程序的可读性,易维护性,提高程序的运行效率。 - 软件测试
在软件设计完成后要经过严密的测试,以发现软件在整个设计过程中存在的问题并加以纠正。整个测试过程分单元测试、组装测试以及系统测试三个阶段进行。测试的方法主要有白盒测试和黑盒测试两种。在测试过程中需要建立详细的测试计划并严格按照测试计划进行测试,以减少测试的随意性。 - 运行维护
软件维护是软件生命周期中持续时间最长的阶段。在软件开发完成并投入使用后,由于多方面的原因,软件不能继续适应用户的要求。要延续软件的使用寿命,就必须对软件进行维护。软件的维护包括纠错性维护和改进性维护两个方面。
1.2 软件生命周期模型
从概念提出的那一刻开始,软件产品就进入了软件生命周期。在经历需求、分析、设计、实现、部署后,软件将被使用并进入维护阶段,直到最后由于缺少维护费用而逐渐消亡。这样的一个过程,称为"生命周期模型"(Life Cycle Model)。
典型的几种生命周期模型包括瀑布模型、快速原型模型、迭代模型。
瀑布模型的特点(文档是主体),很多的问题在最后才会暴露出来。迭代模型比瀑布模型问题暴露的要早;快速原型法比瀑布模型直观。
1.3 软件测试概念
广义概念:指软件生存周期中所有的检查、评审和确认工作,其中包括了对分析、设计阶段,以及完成开发后维护阶段的各类文档、代码的审查和确认
狭义概念:识别软件缺陷的过程,即实际结果与预期结果的不一致
- 软件测试目的
测试的目的就是发现软件中的各种缺陷
测试只能证明软件存在缺陷,不能证明软件不存在缺陷
测试可以使软件中缺陷降低到一定程度,而不是彻底消灭
以较少的用例、时间和人力找出软件中的各种错误和缺陷,以确保软件的质量 - 软件测试原则
Good-enough: 一种权衡投入/产出比的原则
保证测试的覆盖程度,但穷举测试是不可能的
所有的测试都应追溯到用户需求
越早测试越好,测试过程与开发过程应是相结合的
测试的规模由小而大,从单元测试到系统测试
为了尽可能地发现错误,应该由独立的第三方来测试
不能为了便于测试擅自修改程序
既应该测试软件该做什么也应该测试软件不该做什么 - 软件测试的的重点
测试用例的设计
– 测试用例的设计是整个软件测试工作的核心
– 测试用例反映对被测对象的质量要求,决定对测试对象的质量评估
测试工作的管理
– 尤其是对包含多个子系统的大型软件系统,其测试工作涉及大量人力和物力,有效的测试工作管理是保证有效测试工作的必要前提
测试环境的建立
– 测试环境应该与实际测试环境一致
1.4 软件测试方法
- 黑盒测试
什么是黑盒测试
– 又称功能测试或数据驱动测试,是针对软件的功能需求/实现进行测试,通过测试来检测每个功能是否符合需求,不考虑程序内部的逻辑结构
黑盒测试方法
– 功能划分
– 等价类划分
– 边界值分析
– 因果图
– 错误推测等 - 什么是白盒测试
– 白盒测试也称结构测试或逻辑驱动测试,必须知道软件内部工作过程,通过测试来检测软件内部是否按照需求、设计正常运行
– 白盒测试的主要方法
– 对应于程序的一些主要结构:语句、分支、逻辑路径、变量;白盒测试的主要方法是:
– 语句覆盖方法
– 分支覆盖方法
– 逻辑覆盖方法 - 什么是动态测试
动态测试需要在开发/测试环境或实际运行环境中运行软件,并使用测试用例去查找软件缺陷;动态测试包括功能确认与接口测试、覆盖率分析、性能分析、内存分析等 - 什么是静态测试
静态测试不实际运行软件,主要是对软件的编程格式、结构等方面进行评估.静态测试包括代码检查、程序结构分析、代码质量度量等。它可以由人工进行,也可以借助软件工具自动进行 - 手工测试和自动测试
a.手工测试缺点在于测试工作量大,重复多,回归测试难以实现
b.自动测试利用软件测试工具自动实现全部或部分测试工作:管理、设计、执行和报告;节省大量的测试开销,并能够完成一些手工测试无法实现的测试
手工完成测试的全部过程无法保证测试的科学性与严密性:
– 修改的缺陷越多,回归测试越困难
– 没有人能向决策层提供精确的数据以度量当前的工作进度及工作效率
– 反复测试带来的倦怠情绪及其他人为因素使得测试标准前后不一
– 测试花费的时间越长,测试的严格性也就越低
自动测试将测试人员从反复、烦杂的测试执行中解放出来,用更多的时间进行测试设计和结果分析
软件测试不可能完全自动化
不能完成所有手工测试任务
无创造性且灵活性差,不能改进测试的有效性
过程中可能会遇到许多意想不到的问题,特别是当软件不稳定时
测试脚本的维护高
1.5 测试流程
单元测试
集成测试
系统测试
用户验收测试
回归测试
- 单元测试
完成对最小的软件设计单元—模块的验证工作
目标是确保模块被正确地编码
使用过程设计描述作为指南,对重要的控制路径进行测试以发现模块内的错误
通常情况下是面向白盒的
对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早地发现和解决不易显现的错误
单元测试的内容
– 接口测试
– 内部数据结构
– 全局数据结构
– 边界
– 语句覆盖,错误路径 - 14.集成测试
通过测试发现与模块接口有关的问题
目标是把通过了单元测试的模块拿来,构造一个在设计中所描述的程序结构
应当避免一次性的集成(除非软件规模很小),而采用增量集成
集成测试主要内容
API
API/参数组合 - 系统测试
根据软件需求规范的要求进行系统测试,确认系统满足需求的要求
系统测试人员相当于用户代言人
在需求分析阶段要确定软件的可测性,保证有效完成系统测试工作
系统测试主要内容
所有功能需求得到满足
所有性能需求得到满足
其他需求(例如安全性、容错性、兼容性等)得到满足 - 用户验收/确认测试
Alpha测试
– 是由用户在开发者的场所来进行的,Alpha测试是在一个受控的环境中进行的
Beta测试
– 由软件的最终用户在一个或多个用户场所来进行的,开发者通常不在现场,用户记录测试中遇到的问题并报告给开发者 - 压力测试VS性能测试
性能测试的目的不是去找bugs,而是排除系统的瓶颈,以及为以后的回归测试建立一个基准。而性能测试的操作,实际上就是一个非常小心受控的测量分析过程。在理想的情况下,被测软件在这个时候已经是足够稳定了。
性能测试是为了检查系统的反映,运行速度等性能指标,他的前提是要求在一定负载下,如检查一个网站在100人同时在线的情况下的性能指标,每个用户是否都还可以正常的完成操作等。
概括就是:在不同负载下(负载一定)时,通过一些系统参数(如反应时间等)检查系统的运行情况;
压力测试是为了发现系统能支持的最大负载,他的前提是要求系统性能处在可以接受的范围内,比如经常规定的叶面3秒钟内响应;概括就是:在性能可以接受的前提下,测试系统可以支持的最大负载。
举例说明:针对一个网站进行测试,模拟10到50个用户就是在进行常规性能测试,用户增加到1000乃至上万就变成了压力/负载测试。如果同时对系统进行大量的数据查询操作,就包含了强度测试。
2. Linux入门篇
2.1 Linux操作系统简介
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。
1991年的10月5日,Linux创始人林纳斯·托瓦兹(Linus Torvalds)在comp.os.minix新闻组上发布消息,正式向外宣布Linux内核的诞生,1994年3月,Linux 1.0发布,代码量17万行,当时是按照完全自由免费的协议发布,随后正式采用GPL(General Public License的缩写,是一份GNU通用公共授权)协议。
Linux具有如下优点:
稳定、免费或者花费少
安全性高
多任务,多用户
耗资源少
由于内核小,所以它可以支持多种电子产品,如:Android手机、PDA等。
2.2 Linux发展趋势
随着IT产业的不断发展,用户对网站体验要求也越来越高,而目前主流网站后端承载系统都是Linux系统,目前Android手机全部基于Linux内核研发。企业大数据、云存储、虚拟化等先进技术都是基于Linux系统。
2.3 Linux系统安装
在安装Linux系统之前,先来了解windows系统结构,windows系统一般是安装在C盘系统盘,同样Linux也有类似的系统盘(/根分区),Linux通常分区为(根分区/、swap分区),Linux系统以文件的存储方式,所有的文件都是存储在某个目录下的,类似于windows的文件夹。
对于文件系统的属性来说,windows文件系统类型一般是ntfs、fat32等,而Linux文件系统类型则为ext2、ext3、ext4等(文件系统:是操作系统用于明确磁盘或分区上的文件的方法和数据结构,文件系统由三部分组成:与文件管理有关软件、被管理文件以及实施文件管理所需数据结构。)
安装 Linux系统是每一个初学者的第一个门槛。在这个过程中间,最大的困惑莫过于给硬盘进行分区。虽然现在各种发行版本的 Linux 已经提供了友好的图形交互界面,但是很多人还是感觉无从下手。这其中的原因主要是不清楚 Linux 的分区规定。就好比如果我们了解了windows分区的规则,系统盘C、数据盘D等,就很好分区了。
在 Linux 中规定,每一个硬盘设备最多只能有 4个主分区(其中包含扩展分区)构成,任何一个扩展分区都要占用一个主分区号码,也就是在一个硬盘中,主分区和扩展分区一共最多是 4 个。
下面正式来安装Linux系统,安装系统前需要准备如下软件:
VMware workstation 10.0
CentOS 5.8 x86_i386.iso
安装图解如下:
第一步,新建虚拟机如下图:
第二步,选择相关选项,如下图:
第三步选择“稍后安装操作系统”,如下图:
第四步,选择客户机操作系统类型如下图:
第五步,设置虚拟机硬盘大小为20G,最低不能小于5G,如下图:
第六步,虚拟机新建完成,如下图:
第七步,修改虚拟机内存为512M,并添加ISO镜像,如下图:
自此,虚拟机新建完成,接下来点击“启动此虚拟机”进行Linux系统安装,Linux系统安装图解如下:
第一步,进入安装界面,直接按Enter回车键即可。
第二步,光盘检测,选择SKIP跳过。
第三步,选择安装过程中的语言,初学者可以选择“简体中文”。
第四步,选择初始化整个硬盘,清除所有数据。
第五步,选择分区方式为“自定义分区“。
第五步,点击“新建“-首先创建一个swap交换分区,大小为物理内存的2倍(1024M)。
第六步,继续创建分区,选择“新建“,然后创建根分区/,如下图选择,大小为剩余所有空间即可。
第七步,默认点击下一步,同时默认DHCP配置,时钟选择上海,去掉UTC勾,点击下一步。
第八步,设置root密码,至少六位,点击下一步。
第九步,系统安装包选择,这里选择“现在定制“。
第十步,系统安装包选择,左侧选择“开发“----右侧选择”开发工具“和“开发库”,语言选择“支持中文“,其他一概不选择。
安装完毕会提示“reboot“,直接回车即可。
2.4 Linux学习技巧
初学者可以自己安装虚拟机,然后把linux常用命令例如cd、ls、chmod、useradd、vi等等多练习几十遍,把自己敲打命令的熟练程度提升上来。
然后根据文档搭建Linux下常见的各种服务(DHCP、SAMBA、DNS、Apache、Mysql等),遇到问题后可以在google搜索,搜索的时候多看几篇文章,综合最好的文章来解决问题。
能够熟练的搭建服务后,理解每个服务的完整配置和优化,可以拓展思维。例如LAMP,我们一般是把所有服务放在一台机器上,如果分开多台该如何部署呢?等等。
平时多积累shell编程,可以在网上查找前辈们写的非常好的shell,自己下载下来多练习几遍,从中吸取,不断提高。
建立一个自己的学习博客,把平时工作学习中的知识都记录在里面,这样也可以供别人来参考同时也能提高自己的编写文档及方案的能力。
通过以上学习能够满足企业的一般应有,需要达到资深级别,还需要深入学习集群架构、负载均衡、自动化运维、运维开发等知识。最后还是一句话:多练习才是硬道理!实践出真知!
3. Linux系统篇
3.1 Linux目录初识
通过前面的学习,我们已经能够独立安装完一个linux系统,那接下来我们来熟悉一下Linux系统里面的各个目录文件夹的大致功能:
主要的目录树的有/、/root、/home、/usr、/bin等目录。下面是一个典型的linux目录结构如下: (附图表)
/ 根目录
/bin 存放必要的命令
/boot 存放内核以及启动所需的文件
/dev 存放设备文件
/etc 存放系统配置文件
/home 普通用户的宿主目录,用户数据存放在其主目录中
/lib 存放必要的运行库
/mnt 存放临时的映射文件系统,通常用来挂载使用。
/proc 存放存储进程和系统信息
/root 超级用户的主目录
/sbin 存放系统管理程序
/tmp 存放临时文件
/usr 存放应用程序,命令程序文件、程序库、手册和其它文档。
/var 系统默认日志存放目录
3.2 Linux常用命令
默认进入系统,我们会看到这样的字符: [root@localhost ~]#,其中#代表当前是root用户登录,如果是$表示当前为普通用户。
我们了解linux由很多目录文件构成,那我们来学习第一个Linux命令:
cd命令, cd /home ;解析:进入/home目录
cd /root 进入/root目录 ;cd …/返回上一级目录;cd ./当前目录;(.和…可以理解为相对路径;例如cd /hom/test ,cd加完整的路径,可以理解为绝对路径)
接下来继续学习更多的命令:
ls ./ 查看当前目录所有的文件和目录。
ls -a 查看所有的文件,包括隐藏文件,以.开头的文件。
pwd显示当前所在的目录。
mkdir创建目录,用法mkdir test ,命令后接目录的名称。
rmdir 删除空目录
rm 删除文件或者目录,用法 rm –rf test.txt (-r表示递归,-f表示强制)。
cp 拷贝文件,用法,cp old.txt /tmp/new.txt ,常用来备份;如果拷贝目录
需要加 –r参数。
mv 重命名或者移动文件或者目录,用法, mv old.txt new.txt
touch 创建文件,用法,touch test.txt,如果文件存在,则表示修改当前文件时间。
Useradd创建用户,用法 useradd wugk ,userdel删除用户。
Groupadd创建组,用法 groupadd wugk1 ,groupdel删除组。
find查找文件或目录,用法 find /home -name “test.txt”,命令格式为:
find 后接查找的目录,-name指定需要查找的文件名称,名称可以使用表示所有。
find /home -name “.txt” ;查找/home目录下,所有以.txt结尾的文件或者目录。
vi 修改某个文件,vi有三种模式:
命令行模式、文本输入模式、末行模式。
默认vi打开一个文件,首先是命令行模式,然后按i进入文本输入模式,可以在文件里写入字符等等信息。
写完后,按esc进入命令模式,然后输入:进入末行模式,例如输入:wq表示保存退出。
如果想直接退出,不保存,可以执行:q!, q!叹号表示强制退出。
cat 查看文件内容,用法 cat test.txt 可以看到test.txt内容
more 查看文件内容,分页查看,cat是全部查看,如果篇幅很多,只能看到最后的篇幅。可以使用cat和more同时使用,例如: cat test.txt |more 分页显示text内容,|符号是管道符,用于把|前的输出作为后面命令的输入。
echo 回显,用法 echo ok,会显示ok,输入什么就打印什么。
echo ok > test.txt ;把ok字符覆盖test.txt内容,>表示追加并覆盖的意思。>>两个大于符号,表示追加,echo ok >> test.txt,表示向test.txt文件追加OK字符,不覆盖原文件里的内容。
初学者常见的命令就如上所示,当然还有很多深入的命令需要学习,后面的附件会讲解。
3.3 Linux用户权限
在Linux操作系统中,root的权限是最高的,相当于windows的administrator,拥有最高权限,能执行任何命令和操作。在系统中,通过UID来区分用户的权限级别,UID等于0,表示此用户具有最高权限,也就是管理员。其他的用户UID依次增加,通过/etc/passwd用户密码文件可以查看到每个用户的独立的UID。
每一个文件或者目录的权限,都包含一个用户权限、一个组的权限、其他人权限,例如下:
标红第一个root表示该文件所有者是root用户,第二个root代表该文件的所属的组为root组,其他用户这里默认不标出。
[root@node1 ~]# ls -l monitor_log.sh
-rw-r–r-- 1 root root 91 May 7 20:21 monitor_log.sh
[root@node1 ~]#
如果我们想改变某个文件的所有者或者所属的组,可以使用命令chown
chown –R test:test monitor_log.sh即可。
每个Linux文件具有四种访问权限:可读®、可写(w)、可执行(x)和无权限(-)。
利用ls -l命令可以看到某个文件或目录的权限,它以显示数据的第一个字段为
准。第一个字段由10个字符组成,如下:
[root@node1 ~]# ls -l monitor_log.sh
-rw-r–r-- 1 root root 91 May 7 20:21 monitor_log.sh
[root@node1 ~]#
第一位表示文件类型,-表示文件,d表示目录;后面每三位为一组。
第一组:2-4位表示文件所有者的权限,即用户user权限,简称u
第二组:5-7位表示文件所有者所属组成员的权限,group权限,简称g
第三组:8-10位表示所有者所属组之外的用户的权限,other权限,简称o
从上面这个文件,我们可以看出,monito_log.sh文件对应的权限为:
root用户具有读和写的权限,root组具有读的权限,其他人具有读的权限。
为了能更简单快捷的使用和熟悉权限,rwx权限可以用数字来表示,分别表示为r(4)、w(2)、x(1)。
Monitor_log.sh权限可以表示为:644
如果给某个文件授权,命令为chmod:chmod 777 monitor_log.sh
3.4 Linux网络配置
熟悉了常用的命令和Linux权限,那接下来如何让所在的Linux系统上网呢?管理linux服务器网络有哪些命令呢?
Linux服务器默认网卡配置文件在/etc/sysconfig/network-scripts/下,命名的名称一般为:ifcfg-eth0 ifcfg-eth1 ,eth0表示第一块网卡,eth1表示第二块网卡,依次类推。一般DELL R720标配有4块千兆网卡。
修改网卡的IP,可以使用命令: vi /etc/sysconfig/network-scripts/ifcfg-eth0 如果是DHCP获取的IP,默认配置如下:
Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0
BOOTPROTO=dhcp
HWADDR=00:0c:29:52:c7:4e
ONBOOT=yes
TYPE=Ethernet
如果是静态配置的IP,ifcfg-eth0网卡配置内容如下:
Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0
BOOTPROTO=static
HWADDR=00:0c:29:52:c7:4e
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.33.10
NETMASK=255.255.255.0
GATEWAY=192.168.33.1
网卡参数详解如下:
DEVICE=eth0 #物理设备名
ONBOOT=yes # [yes|no](重启网卡是否激活设备)
BOOTPROTO=static #[none|static|bootp|dhcp](不使用协议|静态分配|BOOTP协议|DHCP协议)
TYPE=Ethernet #网卡类型
IPADDR=192.168.33.10 #IP 地址
NETMASK=255.255.255.0 #子网掩码
GATEWAY=192.168.33.1 #网关地址
网卡配置完毕,重启网卡,命令: /etc/init.d/network restart 即可。
查看ip命令:ifconfig 查看当前服务器所有网卡的IP,可以单独指定,ifconfig eth0 查看eth0的IP地址。
网卡配置完毕,如果来配置DNS,首先要知道DNS配置在哪个目录文件下,vi /etc/resolv.conf 文件:
在该文件里面添加如下两条:
nameserver 202.106.0.20
nameserver 8.8.8.8
从上到下,分别表示主DNS,备DNS。配置完毕后,不需要重启网卡,DNS立即生效。
可以ping www.baidu.com 看看效果:
IP配置完毕后,我们可以通过远程工具来连接Linux服务器,常见的Linux远程连接工具有:putty、secureCRT(主流)、xshell、xmanger等工具。
下载安装secureCRT,打开工具,然后如图配置:
点击左上角quick connect快速连接,弹出界面,然后输入IP,用户名,端口默认是22,然后点击下方的connect连接,会提示输入密码,输入即可。
弹出输入密码框:
进入远程界面,与服务器真实登录一样,然后可以执行命令:
通过这几章的学习,我们已经熟练了Linux常用命令的操作,权限网络、网络配置、远程连接等知识,那接下来我们还能做什么呢?我们已经差不多入门了,接下来就是更进一步的服务配置,Linux系统到底用来做什么呢?接下来的章节将跟大家一起来学习。
Linux系统的应用,我们最开始介绍的时候简单介绍过,目前大中型企业都用它来承载web网站、数据库、虚拟化平台等,那接下来我们将在Linux系统安装各种服务和软件来实现Linux真正的价值。
4. Linux编程篇
4.1 Shell编程简介
shell是操作系统的最外层。shell合并编程语言以控制进程和文件,以及启动和控制其它程序。shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。
Shell是用户与Linux操作系统之间沟通的桥梁。用户可以输入命令执行,又可以利用 Shell脚本编程去运行。随着Linux企业应用越来越多,维护Linux日常工作频繁,所以如果单靠手工去敲打命令是非常困难的,所以学会熟练使用SHELL编程是每个Linux SA必备的功课。
Linux Shell种类非常多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh)等。不同的Shell语言的语法有所不同,所以不能交换使用。
最常用的shell是Bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用,也是大多数Linux系统默认的Shell。接下来我们来写一个简单的shell脚本。(shell脚本一般文件名以.sh结尾,同时文件第一行定义该脚本为shell脚本)
vi first_shell.sh
#!/bin/bash
#This is my First shell
echo “Hello World !”
这就是我们的第一个脚本,是不是很简单呢,注解如下:
#!/bin/bash //表示定义该脚本是一个shell脚本(固定格式)。
#This is my First shell //这里的#号属于注解,没有任何的意义,SHELL不会解析它。
echo “Hello World !” //shell脚本主命令,我们执行这个脚本讲看到: Hello World ! 信息。
脚本编写完毕,如何来执行呢,首先执行shell脚本需要执行权限,赋予执行权限:
chmod o+x first_shell.sh 然后./first_shell.sh执行即可;也可以直接使用命令执行: /bin/sh first_shell.sh,显示效果一样。
4.2 Shell变量设置
Shell编程语言是非类型的解释型语言,不像C++/JAVA语言编程时需要事先声明变量,SHELL给一个变量赋值,实际上就是定义了变量,在Linux支持的所有shell中,都可以用赋值符号(=)为变量赋值。
SHELL变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell脚本中使用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。
例如在脚本里面定义A=123 ,定义这样一个变量,前面变量名,后面是变量的值。
引用变量可以使用$A,把变量放在脚本里面会出现什么样的效果呢?如下:
#!/bin/bash
#Author wugk 2014-06-10
A=123
echo “Printf variables equal is $A”
执行脚本:sh test.sh,结果将会显示:
Printf variables equal is 123
简单的理解变量,相当于定义一个别名-名称,引用的时候加上$符号就可以了。
例如定义变量 name=wuguangke
执行echo $name 将会显示wuguangke
SHELL常见的系统变量解析:
$0 当前程序的名称
$n 当前程序的第n个参数,n=1,2,…9
$* 当前程序的所有参数(不包括程序本身)
$# 当前程序的参数个数(不包括程序本身)
$? 命令或程序执行完后的状态,一般返回0表示执行成功。
$UID 当前用户的ID
$PWD 当前所在的目录
4.3 Shell流程控制语句
在Linux Shell编程中,if、for、while、case等条件流程控制语句用的非常多,把这些学好,对提升脚本的功力有非常大的帮助。下面将逐个来讲解具体的用法:
If条件判断语句
If (表达式) #if ( Variable in Array )
语句1
else
语句2
fi
案例一,测试数字大小
#!/bin/sh
NUM=100
if (( $NUM > 4 )) ;then
echo “this num is $NUM greater 4 !”
fi
案例二,测试目录是否存在,不存在则新建(注意,中括号之间必须要空格)
#!/bin/sh
#judge dir exist
if [ ! -d /data/20140515 ];then
mkdir -p /data/20140515
else
echo “This DIR is exist,Please exit …..”
fi
逻辑运算符解析:
-f 判断文件是否存在 eg: if [ -f filename ]
-d 判断目录是否存在 eg: if [ -d dir ]
-eq 等于 应用于:整型比较
-ne 不等于 应用于:整型比较
-lt 小于 应用于:整型比较
-gt 大于 应用于:整型比较
-le 小于或等于 应用于:整型比较
-ge 大于或等于 应用于:整型比较
-a 双方都成立(and) 逻辑表达式 –a 逻辑表达式
-o 单方成立(or) 逻辑表达式 –o 逻辑表达式
-z 空字符串
案例三,多个条件测试判断
#!/bin/sh
scores=80;
if [[ $scores -gt 85 ]]; then
echo "very good!";
elif [[ $scores -gt 75 ]]; then
echo "good!";
elif [[ $scores -gt 60 ]]; then
echo "pass!";
else
echo "no pass!";
fi;
循环语句for
For 变量 in 字符串
do
语句1
done
案例一,打印seq多个数
#!/bin/sh
for i in `seq 15`
do
echo “NUM is $i”
done
案例二,找到相关log,然后批量打包
#!/bin/sh
for i in `find /var/log -name “*.log”`
do
tar –czf 2014log.tgz $i
done
循环语句while
while 条件语句
do
语句1
done
案例一,while条件判断数字
#!/bin/sh
i=1;
while [[ $i -lt 10 ]];do
echo $i;
((i++));
done;
案例二,while逐行读取某个文件
#!/bin/sh
while read line
do
echo $line;
done < /etc/hosts
Until循环语句
until 条件
do
action
done
直到满足条件,才退出。否则执行action。
案例一,条件判断数字
#!/bin/sh
a=10;
until [[ $a -lt 0 ]];do
echo $a;
((a--));
done;
Case选择语句
case $arg in
pattern1)
语句1
;;
pattern2)
语句2
;;
*)
语句3
;;
esac
案例一,创建选择参数脚本
#!/bin/sh
case $1 in
monitor_log)
monitor_log
;;
archive_log)
archive_log
;;
* )
echo "Usage:{$0 monitor_log | archive_log |help }"
;;
esac
select选择语句
#!/bin/sh
PS3="What you like most of the open source system?"
select i in CentOS RedHat Ubuntu
do
echo "Your Select System: "$i
done
4.4 Shell脚本案例
a) 自动删除test.txt文件脚本
脚本的功能实现从/root/目录cp拷贝test.txt到/tmp目录,并且在/tmp目录创建一个目录abc,并且删除原/root/下test.txt。
首先命名脚本名称为auto_cp.sh(名称可以自己定义),内容如下:
#!/bin/bash
#This is First shell for auto cp Files
#定义文件和目录变量
FILES=/root/test.txt
DIR=/tmp
cp $FILES $DIR
cd $DIR ; mkdir –p abc
rm -rf $FILES
echo “The Shell Scripts exec successfully !”
“自动CP并删除文件”的脚本编写完毕,保存退出即可。
b) 自动备份Mysql数据库脚本
#!/bin/sh
#auto backup mysql
#wugk 2012-12-12
#Define PATH定义变量
BAKDIR=/data/backup/mysql/`date +%Y-%m-%d`
MYSQLDB=webapp
MYSQLPW=backup
MYSQLUSR=backup
#must use root user run scripts 必须使用root用户运行,$UID为系统变量
if
[ $UID -ne 0 ];then
echo This script must use the root user ! ! !
sleep 2
exit 0
fi
#Define DIR and mkdir DIR 判断目录是否存在,不存在则新建
if
[ ! -d $BAKDIR ];then
mkdir -p $BAKDIR
else
echo This is $BAKDIR exists....
fi
#Use mysqldump backup mysql 使用mysqldump备份数据库
/usr/bin/mysqldump -u$MYSQLUSR -p$MYSQLPW -d $MYSQLDB >$BAKDIR/webapp_db.sql
echo "The mysql backup successfully "
c) 自动打包tar目录下log文件脚本
#!/bin/sh
#auto tar czf shell to Files
#Author wugk 2014-05-15
SRC_DIR=/opt/
DES_DIR=/opt/backup/`date +%Y%m%d`
If
[ ! –d $DES_DIR ];then
Mkdir –p $DES_DIR
fi
for i in `find $SRC_DIR -name “*.log”`
do
tar czf $i.tgz $i
done
echo “The scripts exec end, Files tar successfully !”
d) 自动拒绝恶意IP脚本
#!/bin/sh
#auto drop ssh failed IP address
#wugk 2013-1-2
#定义变量
SEC_FILE=/var/log/secure
#如下为截取secure文件恶意ip 远程登录22端口,大于等于4次就写入防火墙,禁止以后再登录服务器的22端口
IP_ADDR=`tail -n 1000 /var/log/secure |grep "Failed password"| egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort -nr | uniq -c |awk ' $1>=4 {print $2}'`
IPTABLE_CONF=/etc/sysconfig/iptables
echo
cat <<EOF
++++++++++++++welcome to use ssh login drop failed ip+++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++------------------------------------++++++++++++++++++
EOF
echo -n "请等待5秒后开始执行 "
for ((j=0;j<=4;j++)) ;do echo -n "----------";sleep 1 ;done
echo
for i in `echo $IP_ADDR`
do
#查看iptables配置文件是否含有提取的IP信息
cat $IPTABLE_CONF |grep $i >/dev/null
if
[ $? -ne 0 ];then
#判断iptables配置文件里面是否存在已拒绝的ip,如何不存在就不再添加相应条目
sed -i "/lo/a -A INPUT -s $i -m state --state NEW -m tcp -p tcp --dport 22 -j DROP" $IPTABLE_CONF
else
#如何存在的话,就打印提示信息即可
echo "This is $i is exist in iptables,please exit ......"
fi
done
#最后重启iptables生效
/etc/init.d/iptables restart
4.5 Shell数组编程
数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字成为数组名,编号成为下标。
今天这里我们来探讨一维数组的定义、统计、引用和删除等操作。首先来定义一个一维数组:
A=( test1 test2 test3 ) ,定义数组一般以括号的方式来定义,数组的值可以随机定义。如何来引用呢?
echo ${A[0]},代表引用第一个数组变量,结果会显示test1,数组引用从0开始,代表第一个数组,依次类推。
echo ${A[1]},代表引用第二个数组变量,结果会显示test2,数组引用也是从0开始计算的。
如何显示该数组所有参数呢?echo ${A[@]} 将显示所有参数test1 test2 test3 。
如何显示该数组参数个数呢?echo ${#A[@]} 将显示该数组的参数个数3。
如果替换某个数组呢?例如替换第二个test2数组为test5:echo ${A[@]/test2/test5}
如何删除一个数组呢?例如删除test3数组命令为:unset A[2] ;echo ${A[@]}查看效果。
那输入如何在编程来使用呢?请看下面例子:
#!/bin/sh
#Auto Make KVM Virtualization
#Auto config bond scripts
eth_bond()
{
NETWORK=(
HWADDR=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $1}'`
IPADDR=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $2}'`
NETMASK=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $3}'`
GATEWAY=`route -n|grep "UG"|awk '{print $2}'`
)
cat >ifcfg-bond0<<EOF
DEVICE=bond0
BOOTPROTO=static
${NETWORK[1]}
${NETWORK[2]}
${NETWORK[3]}
ONBOOT=yes
TYPE=Ethernet
NM_CONTROLLED=no
EOF
如上脚本为定义三个数组变量,然后分别来引用,这样让脚本可读性更强,更整洁。关于数组就简单的介绍到这里。