shell脚本二
在shell脚本一 中,我讨论了shell脚本的语法规范,shell脚本的变量,以及shell脚本的测试语句。
仅仅懂得这些只能写简单的脚本,在简单的脚本中各条语句按顺序执行,从而实现自动化的管理,顺序单一执行太过机械化,不够“智能”,难以实现更加灵活的系统任务。甚至一个简单的场景:现有100台linux服务器,其中有50台安装过某软件,有50台没有安装过某软件。如果没有流程控制及循环方面的脚本知识,如此简单的问题,也变得非常低效。所以本文带你走进shell脚本的流程控制及循环的世界。
一、多重条件判定
1、逻辑测试
逻辑测试指的是判断两个或多个条件之间的依赖关系,当系统取决于多个条件时,根据这些条件或其中的一个条件成立等情况来判断系统是否执行或有效。
常用的逻辑测试
&&:逻辑与,“并且而且”的意思 满足两个条件
||:逻辑或,“或者”的意思 满足两个条件中的一个
! 逻辑否
逻辑与 “&&” 是指并且而且的意思,只有前后两个条件都成立时才会返回值为0(成立)否则就是非0(不成立)
使用test进行测试的时候可以改成-a
逻辑或 “||” 只要前后两个条件有一个成立时,则整个侧示命令的返回值即为0
使用test进行测试可以写成 -o 但是在rhel的系统中不支持
逻辑非 “!” 表示不,只有当条件不成立时返回值才会为0否则为非0
逻辑与和逻辑或通常也用于间隔不同的命令操作
补充:
1. 格式:test 测试条件
注意:在使用"["简写test时,左中括号后面的空格和右括号前面的空格是必需的,如果没有空格,Shell不可能辨别表达式何时开始何时结束.
2. 测试范围: 整数,字符串,文件
a.文件状态的检测 (测试时变量应加双引号)
test -e: 目标是否存在(exist)
test -d: 是否为目录(directory)
test -f: 是否为文件(file)
test -x: 文件存在并且可执行
test -r file: 文件存在并且可读
test -w file: 文件存在并且可写
test -s file 测试大小是为空。是否为空文件
test File1 –ef File2 两个文件具有同样的设备号和i结点号
test File1 –nt File2 文件1比文件2 新
test File1 –ot File2 文件1比文件2 旧
test –b File 文件存在并且是块设备文件
test –c File 文件存在并且是字符设备文件
test –f File 文件存在并且是正规文件
test –g File 文件存在并且是设置了组ID
test –G File 文件存在并且属于有效组ID
test –h File 文件存在并且是一个符号链接(同-L)
test –k File 文件存在并且设置了sticky位
test –b File 文件存在并且是块设备文件
test –L File 文件存在并且是一个符号链接(同-h)
test –o File 文件存在并且属于有效用户ID
test –p File 文件存在并且是一个命名管道
test –t FD 文件描述符是在一个终端打开的
test –u File 文件存在并且设置了它的set-user-id位
b. 权限的检测
test -r:是否有读取(read)权限
test -w:是否有写入(write)权限 root对所有者w例外
test -x:是否有可执行(excute)权限
c. 整数值比较
test -eq:等于(equal)
test -ne:不等于(Not equal)
test -gt:大于(greater than)
test -lt:小于(lesser than)
test -ge:大于或等于(greater or equal)
test -le:小于或等于(lesser or equal)
说明:也可以省略test 写成: [ int1 -lt int2 ]
-eq == 等于(equal)
-ne != 不等于(Not equal)
-gt > 大于(greater than)
-ge >= 大于或等于(greater or equal)
-lt < 小于(lesser than)
-le <= 小于或等于(lesser or equal)
提示:“<”和“>””=”分别为小于 大于 等于,并且在[]中“<”“>”都要使用转义字符,在[[]]中不需要。
d 字符串和变量
test $str1 == $str2 是否相等
test $str1!= $str2 是否不相等
test $str1 如果$str1不为空,则返回结果为真
test -n $str1 如果字符串长度为非零,则返回结果为真
test -z $str1 如果字符串长度为零,则返回结果为真
举例1: 通过逻辑表达判断一下两个变量的值


2、数值的比较
数值的比较指的是根据给定的两个整数判断第一个数值与第二个数值的关系
第一个数是否大于小于第二个数
-eq:等于(Equal) Eq
-ne:不等于(Not Equal)
-gt:大于(Greater Than)
-lt:小于(Lesser Than)
-le:小于或等于(Lesser or Equal)
-ge:大于或等于(Greater or Equal)
格式 [ 数值1 操作符 数值2 ]
实战:我们可以通过数值的比较来判断当前的登录用户数量

3.字符串比较
字符串比较通常用来检查用户输入、系统环境是否满足条件、在提供交互式操作的shell脚本中也可以判断用户输入位置参数是否符合要求,字符串的常用操作如下
= 字符串内容相同
!= 字符串内容不同
-z 字符串内容为空
实战1:
若要判断当前系统的语言环境,当发现不是en.US时输出提示信息“$LANG”
$LANG变量是定义当前系统的语言属于环境变量
取反就是不等于的意思

实战2:
-z 判断一个变量的值是否为空

二、if语句
if语句是循环语句中的一种又称为控制语句.通过制定条件进行判断执行;
只有条成立的时候才会执行相对应的代码,否则不会进行任何操作
1. 单分支if语句的格式
if 条件测试操作
then
命令序列
fi
单分支执行结构图:

单分支的结构非常简单,条件成立就执行then命令序列,条件不成立则fi结束
实战1:
如果 /media/cdrom ,目录不存在则 创建这个目录
then根据判断的结果是否执行
如果返回值为0则执行then的命令序列如果不为0则直接结束
[root@xiaolyu ~]# vim file.sh


这就是单分支的应用比较简单。
2. 双分支IF语句
双分支的选择结果,要求针对条件成立,条件不成立两种情况分别执行不同的操作
语法结构:
if 条件测试操作
then(条件成立执行)
命令序列1
else(否则,条件不成立,则执行)
命令序列2
fi
双分支执行结构图:

首先通过if进行条件测试。如果条件成立则执行命令序列1如果不成立则进行命令序列2之后fi结束判断
实战1:
我们编写一个连通性测试脚本通过位置参数$1提供目标主机地址,然后根据ping检测结果给出相应提示
[root@xiaolyu ~]# vim pinghost.sh


将网络关闭,再次执行该脚本:
[root@xiaolyu ~]# systemctl stop network

注释:
-c ping包的次数
-i ping包的间隔
-w 超时的时间间隔
脚本解释:如果if判断为0则接下来执行then输出目标主机up
如果不为0则执行else输出目标主机down
这就是双分支的优势 --- 成立执行成立的操作,不成立则执行不成立的操作;
3-多分支if语句
由于if语句可以根据测试结果的成立,不成立分别执行,所以可以嵌套使用,进行多次判断.
多分支语法格式:
if 条件测试操作1
then
命令序列1
elif 条件测试操作2
then
命令序列2
else
命令序列3
fi
多分支if语句的执行流程

首先判断条件测试操作1的结果,
如果条件1成立,则执行then命令序列1 ,然后跳转至fi结束判断.
如果条件1不成立,则继续判断条件测试2的结果.
如果条件序列2成立则执行命令序列2,然后跳至fi结束判断.
如果所有的条件都不满足则执行else后面的命令序列3直到遇到fi结束
其实多分支的if语句不是很常用,循环语句case这种语句更加简单方便。
实战:
1、编写脚本程序用于监视系统服务httpd的运行状态,要求如下
当服务状态失败时在"/var/log/httpderr.log"文件中记入日志信息。
自动将状态失败的httpd服务重新启动。若重启httpd服务失败,测尝试重新启动服务器主机
[root@xiaolyu ~]# yum -y install httpd

[root@xiaolyu ~]# vim monitorHttpd.sh
#!/bin/bash
systemctl status httpd
if
[ $? -eq 0 ]
then
echo "httpd server is running " >>/dev/null
elif
[ $? -ne 0 ]
then
echo " httpd server running fail. Try to restart" >>/var/log/httpderr.log
systemctl restart httpd
else
echo " server begin restart"
/sbin/shutdown -r now
fi



2、编写uname.sh脚本判断当前系统的内核主版本若大于或等于3 ,则输出当前版本./否则输出提示当前版本太低.
过滤主版本号
uname -r | awk -F . '{print $1}'
过滤出次版本号
uname -r | awk -F . '{print $2}'
显示主次版本号
uname -r | awk -F . '{print $1 $2 }'

vim kernel.sh
#!/bin/bash
primary=$(uname -r | awk -F . '{print $1}')
if
[ $primary -ge 3 ]
then
echo "$(uname -r | awk -F . '{print $1 $2 }')"
else
echo "your kernel is to low!"
fi


三、for循环语句的结构
使用for循环语句时,需要指定一个变量及可能的取值列表。跟对不同的取值,执行相同的命令序列直到变量的值取完遍退出循环。取值列表称为for语句的执行条件
for语句执行的语法结构
for 变量名 in 取值列表
do
命令序列
done

for语句的执行流程
首先将列表的中的第一个值赋予变量,并执行do…done循环体中的命令序列,然后将取值列表中的第二个值赋予变量…列表中的所…一次类推知道有值取完,然后跳到done结束循环
为了进一步理解for语句的结构和流程,掌握for语句在脚本中的实际应用,
实战1: 批量添加用户
有些时候我们的系统需要多个用户的时候,并且用员工姓名的拼音为用户名。这时也可以使用for循环进行创建并设置初始密码,批量创建用户。
1.先将要创建的用户保存到一个文件中。
vim users.txt

查看创建成功的用户

2.编辑一个脚本,添加用户:vim adduser.sh
首先定义一个变量作为取值列表
将取值列表赋予变量user
嵌套一个if语句判断用户是否存在,如果存在则输出用户已存在,否则执行else的命令序列进行添加用户并且设置密码实现取值循环

代码如下:
#!/bin/bash
userlist=$(cat /root/user.txt)
for user in $userlist
do
useradd $user > /dev/null 2>&1
if
[ $? -eq 0 ]
then
echo "123456" | passwd --stdin $user
echo "user $user has added successfully ---!"
else
echo "the user $user has already exists"
fi
done
执行该脚本: . useradd.sh

查看新添加的用户:

再次执行该脚本 . useradd.sh

若要删除刚刚创建的用户可以编写脚本
vim userdel.sh

执行删除用户的脚本: . userdel.sh

实战2:根据ip地址列表检测主机状态
建立一个ip地址取值列表
vim ip.txt

将前面的pinghost.sh的脚本改造成for循环的形式如下:


这就是简单的for循环语句的应用。
shell脚本二的更多相关文章
- 运维常用shell脚本二(压缩文件、过滤不需要的文件、检测进程)
一.压缩指定目录下的文件并删除原文件 #!/bin/bashZIP_DAY=7 function zip { local dir=$1 if [ -d $dir ];then local file_n ...
- Shell脚本(二)数学运算
直接上代码. #!/bin/bash no1= no2= echo "using let ..." let result=no1+no2 echo "result is: ...
- Linux shell脚本编程(二)
Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...
- 《Linux命令行与shell脚本编程大全》 第二十二章 学习笔记
第二十二章:使用其他shell 什么是dash shell Debian的dash shell是ash shell的直系后代,ash shell是Unix系统上原来地Bourne shell的简化版本 ...
- 老李分享:《Linux Shell脚本攻略》 要点(二)
老李分享:<Linux Shell脚本攻略> 要点(二) poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课 ...
- 读《Linux Shell脚本攻略》(第2版) 一遍、二遍体会
前段时间读完了<Linux Shell脚本攻略>(第2版)这本书,给部分想读这本书的人分享下个人感受. 第一遍体会解读:就像黑夜中的灯塔,指明前进的道路. 推荐指数:强烈推荐. 书中讲解的 ...
- shell编程基础(二): shell脚本语法之分支语句和循环语句
一.分支语句 1.条件测试:test [ 命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与 ...
- Shell脚本笔记(二)Shell变量
Shell变量 一)全局环境变量 全局变量对于定义它的shell和其子shell都是可见的,但如果生成它的shell被终止,全局变量也就消失了.另外全局变量会被子shell的同名变量覆盖. #定义一个 ...
- shell脚本(二)
shell脚本(二)——变量 一.定义:用来存放各种数据,编程语言组成部分 变量的命名规则: 变量名由数字 字母下划线组成 必须以字母或者下划线开头 不能使用shell里面的关键词 ...
随机推荐
- Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...
- dojo Provider(script、xhr、iframe)源码解析
总体结构 dojo/request/script.dojo/request/xhr.dojo/request/iframe这三者是dojo提供的provider.dojo将内部的所有provider构 ...
- [ZigBee] 10、ZigBee之睡眠定时器
0.概述 睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期.睡眠定时器还用于当进入低功耗睡眠模式时,维持定时器2 的定时. 睡眠定时器的主要功能如下: ● 24 位的定时器正计数器,运行在32 ...
- 虚拟化平台cloudstack(2)——安装(上)
vmware workstation安装ubuntu server12.04 这个其实没什么说的了,下软件,安装,一顿下一步,OK. 安装完成后,为ubuntu server 12.04安装桌面. 使 ...
- bianma 水平 技巧
能够写出这样的代码, 其实体现了水平 switch (state) { case 0: break; case 3: return; // already connected case 4: stat ...
- Redis学习笔记~StackExchange.Redis实现分布式Session
回到目录 对于多WEB的环境现在已经是必须的了,很难想像一台WEB服务器面对百万并发的响应,所以,我们需要多台WEB服务器集群合作,来缓解这种高并发,高吞吐的场景,而对于多WEB的场景又会有个问题出现 ...
- EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!
回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...
- Dubbo的使用及原理浅析.
前面几个博文中关于SSM 框架已经搭建完成, 这里来讲下项目中使用到的Dubbo以及自己了解到的关于Dubbo的一些知识. Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天 ...
- Atitit 视频编码与动画原理attilax总结
Atitit 视频编码与动画原理attilax总结 1.1. 第一步:实现有损图像压缩和解压1 1.2. 接着将其量化,所谓量化,就是信号采样的步长,1 1.3. 第二步:实现宏块误差计算2 1.4. ...
- Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现)(转)
Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现) 相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦 ...