shell脚本二

丰泽园的天空 丰泽园的天空     2022-08-02     501

关键词:

  在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循环语句的应用。

linux系统shell脚本之用户管理脚本实战(代码片段)

Linux系统shell脚本之用户管理脚本实战一、脚本要求二、脚本内容三、执行脚本1.正确执行脚本2.错误执行脚本一、脚本要求1.使用usage函数,列出该脚本的帮助选项2.检查该脚本的执行用户,若非root用户,直接退出3.该脚本可以管... 查看详情

linux操作系统笔记——shell程序设计(代码片段)

目录一、Shell脚本的概念二、一个Shell脚本的基本步骤三、赋予Shell脚本执行权限(一)Shell调用脚本(二)chmod命令赋予脚本执行权限四、Shell功能性语句(一)read命令读入(二)tput命令(三... 查看详情

linux系统shell脚本之监控httpd服务(代码片段)

Linux系统shell脚本之监控httpd服务一、脚本要求二、脚本内容三、执行脚本1.服务正常进行时检测2.服务故障时检测一、脚本要求1.要求监控服务器的httpd服务是否启动,并且脚本运行后,输出检测结果2.无论检测结果如何,脚本执... 查看详情

linux系统shell脚本之过滤文本关键字(代码片段)

Linux系统shell脚本之过滤文本关键字一、脚本要求二、脚本内容三、执行脚本一、脚本要求1.要求过滤passwd文件中所有的用户名2.要求查找用户名的字符在三个字符以上的用户二、脚本内容[root@192scripts]#cat./word_wl.sh#!/bin/bash#######... 查看详情

shell脚本应用

...;          第六章shell脚本应用(二)前言:为了使shell脚本具有一定的“判断”能力,根据不同的条件来完成不同的管理任务。使脚本具有一定的“智能”。目标:学会使用条件测试 查看详情

shell全解析:shell脚本(代码片段)

文章目录一、前言二、Shell脚本2.1从Shell到Shell脚本2.2编写Shell脚本2.3执行Shell脚本三、Shell脚本内对参数的操作四、Shell脚本中常见命令4.1Shellecho命令4.1.1echo中直接输出普通字符串4.1.2echo中显示转义字符4.1.3echo中读取输入4.1.4echo换... 查看详情

linux系统shell脚本之向指定终端发送消息(代码片段)

Linux系统shell脚本之向指定终端发送消息一、脚本要求二、脚本内容三、编辑消息内容四、发送消息到终端五、到登录用户终端查看消息一、脚本要求向正在登录的admin用户终端界面发送一条测试信息二、脚本内容[root@masteruser]... 查看详情

shell教程二----shell变量,通配符,转义符(代码片段)

...0c;表示不同的功能$n功能描述:n为数字,$0代表该脚本名称,$1、$2、$3、$4、$5表示运行脚本时,传给程序的参数,用空格分开,十以上的参数需要用大括号包含,如$10$#功能描述:传给shell脚本参数... 查看详情

shell脚本变量与运算符(代码片段)

Shell脚本(一)概述、解析器、脚本入门Shell脚本(二)变量与运算符Shell脚本(三)条件判断与流程控制Shell脚本(四)”read读取控制台输入”与“函数”Shell脚本(五)Shell工具及企业面试... 查看详情

shell全解析:shell脚本程序(代码片段)

文章目录一、前言二、Shell脚本中的流程控制2.1条件判断2.2循环2.2.1for循环2.2.2while循环三、Shell脚本中的函数3.1Shell函数的定义和调用3.2Shell函数内操作实参四、Shell脚本中的输入/输出重定向4.1重定向与重定向命令4.2输出重定向4.3... 查看详情

shell脚本”read读取控制台输入”与“函数”

Shell脚本(一)概述、解析器、脚本入门Shell脚本(二)变量与运算符Shell脚本(三)条件判断与流程控制Shell脚本(四)”read读取控制台输入”与“函数”Shell脚本(五)Shell工具及企业面试... 查看详情

shell脚本怎么调用其他shell脚本

参考技术A在Shell中要如何调用别的shell脚本,或别的脚本中的变量,函数呢?方法一:../subscript.sh方法二:source./subscript.sh注意:1.两个点之间,有空格,千万注意.2.两个脚本不在同一目录,要用绝对路径3.为简单起见,通常用第一种方... 查看详情

linux之shell脚本实战统计linux进程相关数量信息(代码片段)

【Linux之shell脚本实战】统计Linux进程相关数量信息一、脚本要求二、检查本地服务器状态1.检查系统版本2.检查系统内核版本三、配置脚本注释模板1.编辑.vimrc文件2.检查模板生效情况四、编写ps_aa.sh脚本五、查看脚本效果一、脚... 查看详情

shell脚本快速编写入门(代码片段)

参考:shell脚本入门作者:~莘莘发布时间:2021-07-1623:26:04网址:https://blog.csdn.net/lcx1837/article/details/118761051?spm=1001.2014.3001.5501目录一、什么是shell脚本:二、shell脚本写法:三、sh 查看详情

shell脚本基础——shell运行原理+变量数组定义(代码片段)

...言2)解释型语言2.shell运行原理3.小结4.什么时候用到脚本?二、Shell脚本的基本用法1.脚本的基本写法2.脚本执行方法1)标准脚本执行方法2)非标准的执行方法3.bash基本特性1)常用快捷键2)常用的通配符4.... 查看详情

shell脚本之if使用语句进行条件测试(代码片段)

使用test测试命令时,多数使用“[条件表达式]”,条件表达式与方括号之间至少需要有一个空格。1、文件测试:-d:测试是否为目录;-f:测试是否为文件;-e:测试是否文件或目录存在;-r:测试当前用户是否有权限读取;-w:... 查看详情

shell脚本的调试方法(代码片段)

Shell提供了一些用于调试脚本的选项,如下所示:-n读一遍脚本中的命令但不执行,用于检查脚本中的语法错误-v一边执行脚本,一边将执行过的脚本命令打印到标准错误输出-x提供跟踪执行信息,将执行的每一条命令和结果依次... 查看详情

linux之shell脚本实战监控系统的磁盘空间使用率(代码片段)

【Linux之Shell脚本实战】监控系统的磁盘空间使用率一、脚本要求二、检查本地系统环境1.检查系统版本2.检查系统内核版本三、编写disk.sh脚本1.创建脚本目录2.编写disk.sh脚本3.执行测试脚本四、查看脚本执行日志文件五、本次实... 查看详情