一、分享的目标
希望大家通过对本次分享内容的阅读可以了解SHELL,在日常工作中能通过SHELL实现简单的功能,提高工作效率。本次分享的重点在案例分享部分,前面基础部分是为了让SHELL基础薄弱的同事通过阅读学习能读懂最后案例分享中脚本的内容。
二、分享的大纲
1.SHELL简介
2.流程控制
3.条件判断
4.循环
5.算术运算
6.变量的作用域和常用隐含变量
7.简单调试
8.案例分享(重点)
三、具体内容
1.SHELL简介
SHELL本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。SHELL既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,SHELL脚本和编程语言很相似,有变量和流程控制语句。SHELL脚本是解释执行的,不需要编译,SHELL程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到SHELL提示符下顺序执行。
2.流程控制
(1).if 语句
提供条件测试。测试可以基于各种条件。例如文件的权限、长度、数值或字符串的比较。这些测试返回值或者为真(0),或者为假(1)。基于此结果,可以进行相关操作。
(2).case语句
允许匹配模式、单词或值。一旦模式或值匹配,就可以基于这个匹配条件进行相关操作。
3.条件判断
(1).文件属性的判断
操作符 测试结果
-e filename 文件存在返回1,否则返回0
-r filename 文件可读返回1,否则返回0
-w filename 文件可写返回1,否则返回0
-x filename 文件可执行返回1,否则返回0
-o filename 文件属于用户本人返回1,否则返回0
-z filename 文件长度为0返回1,否则返回0
-f filename 文件为普通文件返回1,否则返回0
-d filename 文件为目录文件时返回1,否则返回0
(2).字符串比较
操作符 比较结果
str1 = str2 当两个字串相等时为真
str1 != str2 当两个字串不等时为真
-n str1 当字符串的长度大于0时为真
-z str1 当字符串的长度为0时为真
str 当字符串为非空时为真
(3).数值比较(整数)
操作符 比较结果
num1 -eq num2 两数相等为真
num1 -ne num2 两数不等为真
num1 -gt num2 num1大于num2为真
num1 -ge num2 num1大于等于num2为真
num1 -lt num2 num1小于num2为真
num1 -le num2 num1小于等于num2为真
4.循环
循环是一系列命令的重复执行过程,常用的有3种循环语句:
(1).for 循环
每次依次处理列表内信息,直至循环耗尽。
例如:
for i in $(seq 1 10)
do
echo $i
done
(2).Until 循环
此循环语句不常使用,until循环直至条件为真。条件部分在循环末尾部分。
例如:
i=1
until [ $i -gt 10 ]
do
echo $i
i=$(( $i + 1 ))
done
(3).While 循环
while循环当条件为真时,循环执行,条件部分在循环头。
例如:
i=1
while [ $i -le 10 ]
do
echo $i
i=$(( $i + 1 ))
done
5.算术运算
(1).整数运算
expr 例如:i=`expr 1 + 2`
(()) 例如:((i=1+2))
let 例如:let i=1+2
$[] 例如:i=$[1+2]
(2).浮点数运算
bc
特殊变量:
ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;
scale 小数保留位数,默认保留0位。
例如:
echo "scale=5;9+8-7*6/5^2"|bc 输出:15.32000
echo "ibase=16;obase=2;ABC"|bc 输出:101010111100
6.变量的作用域和常用隐含变量
(1).随着代码越写越多,你开始把重复的逻辑提炼成函数。有可能你会掉到shell的一个坑里。在shell中,如果不加local限定词,变量默认都是全局的,但很少有 bash 教程一开始就告知你这个事实。在顶级作用域里,是否是全局变量并不重要。但是在函数里面,声明一个全局变量可能会“污染”到其它作用域(尤其在你根本没有注意到这一点的情况下)的同名变量。所以,对于在函数内声明的变量,请务必记得加上local限定词。
(2).常用隐含变量
$0 当前执行的脚本或者命令名称
$1-$9 代表参数的位置. 举例 $1 代表第一个参数.
$# 脚本调用的参数的个数
$@ 所有参数的内容
$* 所有参数的内容
$$ 当前运行脚本的进程号
$? 命令执行后返回的状态
$! 后台运行的最后一个进程号
注意:
$? 用于检查上一个命令执行是否正确(命令退出状态为0表示该命令正确执行,任何非0值表示命令出错)
$$ 变量最常见的用途是用做暂存文件的名字以保证暂存文件不会重复。
$* 和 $@ 如果输出是一样的,但是在使用for循环,在使用 双引号("")引用时 "$*" 会输
出成一个元素 而 "$@" 会按照每个参数是一个元素方式输出。
7.简单调试
(1).检查语法
-n 选项只做语法检查,而不执行脚本。
例如:sh -n script_name.sh
(2).脚本调试执行
sh -x script_name.sh
进入调试模式后,Shell依次执行读入的语句,产生的输出中有的带加号,有的不带,如下
。带加号表示该条语句是Shell执行的。不带加号表示该语句是Shell产生的输出。
(3).代码块调试上面的-x选项是调试整个脚本的,如果脚本很大,会很不方便,还有一种方法是调试某一块代码的,如下:
set -x
...
code block
...
set +x
这样,只对set -x与set +x之间的代码进行跟踪。
(4).中断调试,在调试过程中可以按Ctrl + Z中断调试,观察结果,然后再按fg键继续调试即可。
8.案例分享(重点)
(1).简介
以下案例是本人在实际工作中编写的,主要是为了提高客户在环境搭建环节的工作效率。
(2).成果
a.未引入自动化安装脚本之前搭建一套环境需要3人/天左右的时间(加上沟通协调等时间),而且经常会因为应用同事填写的参数变量等不合理需不同程度的返工。
b.引入之后搭建一套环境只需要0.5人/天左右的时间,且降低返工的概率。
(3).引入自动化脚本之前环境的搭建流程
①.需要填写复杂的数据库配置文档,大致如下:
......
②.需要将配置文档提交给负责数据库和操作系统的同事评审。
③.负责操作系统的同事需要从配置文档中抽取、计算出来和系统相关的信息,搭建操作系统。
④.负责数据库的同事需要根据配置文件提供的信息,按照标准步骤安装部署环境,整个步骤有30多步,非常耗时。
⑤.安装部署完成后检查环境无问题提交给应用同事使用。
(4).引入自动化脚本之后环境的搭建流程
①.只需提交简单的环境申请表格(详情见附件一,表格中对所填写的内容有严格的限制,确保填写的内容有效。)
②.单击“保存参数配置文件”按钮,选择配置文件保存路径,自动生成操作系统配置文件new_system_config.txt(提供给操作系统的同事搭建环境)和生成数据库配置文件new_db_config.txt(提供给数据库的同时搭建环境)。
new_system_config.txt
new_db_config.txt
③.上传数据库配置文件new_db_config.txt和自动安装脚本(附件二),调用安装脚本,自动完成数据库安装、配置和环境的初始化。
(5).脚本主要实现功能如下,具体实现细节请参考附件二:
说明:脚本具有断点重新开始的功能,运行过程中遇到处理不了的错误脚本会输出错误日志,终止运行;人工根据输出的错误日志信息修复问题后可重跑安装脚本,脚本会检测已经完成的工作,从断点位置开始执行,完成环境的安装部署。
①.自动去FTP服务器取安装包。
②.解压安装包,安装数据库。
③.添加数据库许可。
④.创建数据库实例。
⑤.配置数据库环境变量、实例参数、数据库参数。
⑥.重启数据库、备份数据库使配置生效。
⑦.创建数据库、创建BUFFERPOOL、创建表空间。
⑧.给应用用户赋权(表空间使用权限、数据库通用使用权限等、回收public权限)。
⑨.删除系统自带的临时表空间和用户表空间。
⑩.配置数据库审计策略、开启审计。
⑪.配置数据库锁监控。
⑫.配置数据库dbtools脚本。
⑬.配置实例用户crontab,通过作业循环调用数据库监控脚本。
⑭.配置HA切换脚本。
⑮.设置应用用户环境变量。
⑯.绑包、建立EXPLAIN表等
⑰.给应用用户和db2_mon执行db2advis、db2expln权限。
⑱.清除安装包。
⑲.退出脚本完成安装配置。
⑳.人工检查无问题后提交环境给应用同事使用。
附件一:新建数据库申请表
附件二:数据库自动安装脚本
备注:SHELL脚本db2_ai.sh内容较多,时间有限脚本的注释及函数的封装写的不是很好,还望见谅,如果阅读过程中有任何建议或疑问请及时联系,欢迎一起探讨。