为什么80%的码农都做不了架构师?>>>   

在Shell脚本中执行使用if语句的好处是:可以根据特定的条件(eg:判断备份目录是否存在)来决定是否执行某项操作,当满足不同的条件时执行 不同的操作(eg:备份目录不存在则创建该目录,否则跳过操作)。该文将分别从条件测试操作,if语句结构,应用示例这三个方面讲解if语句在Shell 脚本中的应用。

1、条件测试操作:

需要在Shell脚本中有选择性地执行任务时,首先面临的问题就是,如何设置命令执行的条件?

在Shell环境中,可以根据命令执行后返回状态值来判断该命令是否成功执行,当返回值为0是表示成功执行,否则(非0值)表示执行失败。用于特定条件表达式的测试时,可以使用Linux系统中提供的专用工具——test命令、

使用test测试命令时,可以有以下两种形式。

test       条件表达式

【 条件表达式 】

这两种方式的作用完全相同,但通常后一种形式更为常用,也更贴近编程习惯。需要注意的是,方括号“[”或者“]”与条件表达式语句之间至少需要有一个空格进行分隔。

根据需要判断的条件内容不同,条件操作也不同,最常用的条件主要包括文件状态测试,比较整数值大小,比较字符串,以及同时判断多个条件时的逻辑关系,下面将分别进行讲解。以下主要采用方括号的测试形式。

1.1、测试文件状态

文件状态测试是指根据给定的路径名称,判断该名称对应的是文件还是目录,或者判断文件是否可读,可写,可执行等。根据判断的状态不同,在条件表达式中需要使用不同的操作选项。

-d:测试是否为目录(Directory)。

-e:测试目录或文件是否存在(Exist)。

-f:测试是否为文件(File)。

-r:测试当前用户是否有权限读取(Read)。

-w:测试当前用户是否有权限写入(Write)。

-x:测试当前用户是否可执行(Excute)该文件。

-L:测试是否为符号连接(Link)文件。

执行条件测试操作以后,通过预定义变量“$?”可以获得测试命令的返回状态值,从而能够判断该条件是否成立(返回0值表示条件成立,非0值表示条件不成立)。但通过这种方式查看测试结果会比较繁琐。

例1:测试“/etc/hosts”是否是文件,并通过“$?”变量查看返回状态值,据此判断测试结果。

1
2
3
[ -f /etc/hosts ]
echo $?
0   //返回值为0,表示上一步测试的条件成立。

例2:测试“/media/cdrom/Server”及其父目录是否存在,如果存在则显示“YES”否则不输出任何信息。

1
2
3
4
[ -e /media/cdrom/Server ] && echo "YES"
                                                                         // 无输出表示该目录不 存在
[ -e /media/cdrom ] && echo "YES"
YES

1.2、整数值 比较:

整数值比较是指根据给定的两个整数值,判断第一个数是否大于、等于、小于。。。。。。第2个数,可以使用的操作选项如下:

1
2
3
4
5
6
-eq:第一个数等于(Equal)第二个数。
-ne:第一个数不等于(Not Equal)第二个数。
-gt:第一个数大于(Greater Than)第二个数。
-lt:第一个数小于(Lesser Than)第二个数。
-le:第一个数小于或等于(Lesser or Equal)第二个数。
-ge:第一个数大于或等于(Greater or Equal)第二个数。

整数值比较的测试操作在Shell脚本编写中的应用较多,如:用于判断磁盘使用率、登录用户数量是否超标以及用于控制脚本语句的循环次数等。

例1:测试当前登录到系统中的用户数量是否小于或等于10,是则输出”YES“。

1
2
3
4
who | wc -l
5
[ `who | wc -l` -le 10 ] && echo ”YES"
YES

例2:提取出"/boot“分区的磁盘使用率,并判断是否超过95%(为了便于理解,操作步骤适当进行分解)

1
2
3
4
5
6
df -hT | grep ”/boot“ | awk '{print $6}'
12 %
BootUsage=`df -hT | grep ”/boot " | awk '{print $6}' | cut -d " %" -f 1 `
echo $BootUsage
12
[ $BootUsage -gt 95 ] && echo "YES"    //无输出表示未超标

1.3:字符串比较:

字符串比较可以用于检查用户输入,如:在提供交互式操作时,判断用户输入的选项是否与指定的变量内容相匹配。“=”、“!=”操作选项分别表示匹配、不匹配。“-z”操作选项用于检查字符串是否为空。其中,“!”符号用于取反,表示相反的意思。

eg:提示用户输入一个文件路径,并判断是否是“/etc/inittab”,如果是则显示“YES”.

1
2
3
4
read -p "Location: " FilePath
Location: /etc/inittab           
[ $FilePath = "/etc/inittab" ] && echo "YES"
YES

eg: 若当前环境变量LANG的内容不是“en.US”,则输出LANG变量的值,否则无输出。

1
2
[ $LANG != "en.US" ] && echo $LANG
zh_CN.UTF- 8

eg: 使用touch命令建立一个新文件,测试其内容是否为空,向文件中写入内容后,再次进行测试。

1
2
3
4
5
6
touch zero.file
[ -z `cat zero.file` ] && echo "yes"
yes
echo "something" > zero.file
[ -z `cat zero.file` ] && echo yes
                                                    //无输出

1.4:逻辑测试:

逻辑测试是指同时使用的两个(或多个)条件表达式之间的关系。用户可以同时测试多个条件,根据这些条件是否同时成立或者只要有其中一个条件成立等情况,来决定采取何种操作。逻辑测试可以使用的操作选项如下。

>  &&:逻辑与,表示前后两个表达式都成立时整个测试结果才为真,否则结果为假。在使用test命令形式进程测试时,此选项可以改为" -a"。

>   ||:逻辑或,表示前后两个条件至少有一个成立时整个测试结果即为真,否则结果为假。在使用test命令形式进行测试时,此选项可以改为"-o“。

>  !:逻辑否,表示当指定的条件表达式不成立时,整个测试命令的结果为真。

在上述逻辑测试的操作选项中,”&&“和”||“通常也用于间隔不同的命令操作,其作用是相似的。同时使用多个逻辑运算操作时,一般安装从左到右的顺序进行测试。

eg:测试当前的用户是否是teacher,若不是则提示”Not teacher“。

1
2
3
4
echo $USER
root
[ $USER = “teacher” ] || echo "Not teacher"
Not teacher

eg:只要"/etc/rc.d/rc.local"或者"/etc/init.d/local'中有一个是文件,则显示"YES",否则无任何输出。

1
2
[ -f /etc/rc.d/rc.local ] || [ -f /etc/init.d/rc.local ] && echo "yes“
yes

eg:测试”/etc/profile“文件是否有可执行权限,若确实没有可执行权限,则提示”No x mode.“的信息。

1
2
[ ! -x ”/etc/profile " ] && echo " No x mode."
No x mode.

eg:若当前的用户是root且使用的Shell程序是"/bin/bash",则显示"YES“,否则无任何输出。

1
2
3
4
echo $USER $SHELL
root /bin/bash
[ $USER = ”root " ] && [ $SHELL = " /bin/bash " ] && echo " yes"
yes

2:if语句的结构:

前 面内容知道了一下条件测试操作,实际上使用"&&“和”||“逻辑测试可以完成简单的判断并执行相应的操作,但是当需要选择执行的命令语 句较多时,再使用这种方式将使命令行语句显得很复杂,难以阅读。而使用if语句,则可以更好地体现有选择性执行的程序结构,使得层次分明,清晰易懂。

if语句的选择结构由易到难可以分为三种类型,分别适用于不同的应用场合。

2.1、单分支的if语句。

单分支的if语句是最简单的选择结构,这种结果只判断指定的条件,当”条件成立“时执行相应的操作,否则不做任何操作。单分支使用的语句格式如下。

if 条件测试命令

then

命令序列

fi

在上述语句中,首先通过判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行then后面的一条或多台可执行语句(命令序列),一直到fi为止表示结束,如果条件测试命令的返回值不为0(条件不成立),则直接去执行fi后面的语句。

2.2、双分支的if语句。

双分支的if语句使用了两路命令操作,在”条件成立‘、“条件不成立时分别执行不同的命令序列”。双分支使用的语句格式如下:

if 条件测试命令

then

命令序列1;

else

命令序列2;

fi

在 上述语句中,首先通过if判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行then后面的一条或多条可执行语句(命令序列1),然后跳 转至fi结束判断,如果条件测试命令的返回状态值不为0(条件不成立),则执行else后面的语句,一直到fi表示结束。

2.3、多分支的if语句。

由于if语句可以根据条件测试命令的两种状态分别进行操作,所以能够嵌套使用,进行多次判断(如:首先判断某学生的得分是否及格,如及格则再次判断是否高于90分。。。)多重分支使用的语句格式如下。

if 条件测试命令1

then

命令序列1

elif 条件测试命令2

then

命令序列2

else

命令序列3

fi

上面的语法格式中只嵌套了一个elif语句,实际上if语句中可以嵌套多个elif语句。if语句的嵌套在编写Shell脚本时并不常用,因为多重嵌套容易使程序结构变得复杂。需要使用多重分支程序结构时,更多的是使用case语句来实现。

eg:检查"/var/log/messages'文件是否存在,若存在则统计文件内容的行数并输出,否则不做任何操作。

1
2
3
4
5
6
7
vi  chklog.sh
#!/bin/bash
LogFile= "/var/log/messages"
if [ -f $LogFile ] ; then
wc -l $LogFile
fi
sh chklog.sh                //sh是bash的符号链接

eg:提示用户指定备份目录的路径,若目录已存在则显示提示信息后跳过,否则显示相应提示信息后创建该目录。

1
2
3
4
5
6
7
8
9
[root@master ~]# vi mkbak.sh
#!/bin/bash
read -p "What is your directory:" Bakdir
if [ -d $Bakdir ] ; then
echo "$Bakdir already exist."
else
echo "Bakdir is not exist,will make it."
mkdir $Bakdir
fi

eg:统计当前登录到系统中的用户数量,并判断是否超过三个,若是则显示实际数量并给出警告信息,否则列出登录的用户账号成名及所在终端。

1
2
3
4
5
6
7
8
9
[root@localhost ~]# vim chkuser.sh
#!/bin/bash
UserNum=`who |wc -l`
if [ $UserNum -gt 3 ] ; then
echo "Alert , too many login users ( Total: $UserNum )."
else
  echo "Login users:"
  who | awk '{print $1,$2}'
fi

eg:检 查portmap进程是否已经存在,若已经存在则输出“portmap service is running”;否则检查是否存在“/etc/rc.d/init.d/portmap”可执行脚本,存在则启动portmap服务,否则提示“no portmap script file.”。

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# vim chkportmap.sh
#!/bin/bash
pgrep portmap &> /dev/ null
if [ $? -eq 0 ]; then
echo "protmap service is running."
elif
[ -x "/etc/rc.d/init.d/portmap" ]; then
service portmap start
else
echo "no portmap script file."
fi

eg:每隔五分钟监测一次mysqld服务程序的运行状态,若发现mysqld进程已终止,则在“/var/log/messages”文件中追加写入日志信息(包括当时时间),并重启mysqld服务,否则不进程任何操作。

1
2
3
4
5
6
7
8
9
10
vi chkmysql.sh
#!/bin/bash
service mysqld status &> /dev/ null
if [ $? -ne 0 ]; then
echo "At time:`date`:Mysql Server is down." >> / var /log/messages
service mysqld restart
fi
chmod u+x chkmysql.sh
crontab -e
*/ 5 * * * * /root/chkmysql.sh

3、使用for魂环语句

在Shell脚本中使用for循环语句时,可以为变量设置一个取值列表,每次读取列表中不同的变量值并执行相关命令操作,变量值用完以后则退出循环。Shell中的for语句不需要执行条件判断,其使用变量的取值来自于预先设置的值列表。

for语句结构:

for 变量名 in 取值列表

do

命令序列

done

在 上述语句中,使用in关键字为用户自定义变量设置了一个取值列表(以空格分隔的多个值),for语句第一次执行时首先将列表中的第一个取值赋给该变量。然 后执行do后边的命令序列;然后再将列表中的第二个取值赋给该变量,然后执行do后边的命令序列......如此循环,直到取值列表中的所有值都已经用 完,最后将跳至done语句,表示结束循环。

for语句示例:

eg:依次输出三条文件信息,包括一天中的"Morning"、"Noon"、"Evening"字串。

1
2
3
4
5
6
vi showday.sh
#!/bin/bash
for TM in "Morning" "Noon" "Evening"
do
echo "The $TM of the day."
done

eg:对于使用“/bin/bash”登录Shell的系统用户,检查他们在"/opt"目录中拥有的子目录或文件数量,如果超过100个,则列出具体数量及对应的用户账号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vi chkfileown.sh
#!/bin/bash
DIR= "/opt"                //设置检查的目标目录
LMT= 100                //设置文件数量的限制值
ValidUsers=`grep "/bin/bash" /etc/passwd | cut -d ":" -f 1 `                //找出使用bash的系统用户列表
for UserName in $ValidUsers
do
Num=`find $DIR -user $UserName | wc -l`              //统计每个用户拥有的文件数
if [ $Num -gt $LMT ] ; then
echo "$UserName have $Num files."
fi
done
sh chkfileown.sh
root have 20998 files

4、使用while循环语句

在 Shell脚本中使用while循环语句时,将可以根据 特定的条件重复执行一个命令列表,直到该条件不再满足时为至。除非有特别需要,否则在脚本程序中应该是避免出现无限循环执行命令的情况,因为若无法跳出循 环的话,后边的某些操作将无法执行。为了控制循环次数,通常会在执行的命令序列中包含修改测试条件的语句,当循环达到一定次数后,测试将不再成立,从而可 以结束循环。

while语句的结构:

while 条件测试命令

do

命令序列

done

在 上述语句中,首先通过while判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行do后边的命令序列,然后返回到while再次进行条 件测试并判断返回状态值,如果条件仍然成立,则继续执行do后边的命令序列,然后返回到while重复条件测试......如此循环,直到所测试的条件不 成立时,跳转到done语句,表示结束循环。

使用while循环语句时,有两个特殊的条件测试返回值,即“true” (真)、"false"(假)。使用“true”作为测试条件时,条件将永远成立,循环体内的语句将无限次执行下去,反之使用“false”则条件永远不 成立,循环体内的语句将不会被执行,这两个特殊值也可以用在if语句的条件测试中。

while语句应用示例:

while语句可以用于需要重复操作的循环系统管理任务,并能够通过设置循环条件来灵活的实现各种管理任务。

eg:由用户从键盘输入一个大于1的整数(如50),并计算从1到该数之间各整数的和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# vim sumint.sh
#!/bin/bash
read -p "Input a number (>1):" UP
i= 1
Sum= 0
while [ $i -le $UP ]
do
Sum=`expr $Sum + $i`
i=`expr $i + 1 `
done
echo "The sum of 1-$UP is : $Sum"
[root@localhost ~]# sh sumint.sh
Input a number (> 1 ): 50
The sum of 1 - 50 is : 1275

eg:批量添加20个系统用户账号,用户名称依次为“stu1”、"stu2"、“stu3”、.......“stu20”,各用户的初始密码均设置为“123456”。

1
2
3
4
5
6
7
8
9
[root@localhost ~]# vim add20users.sh
#!/bin/bash
i= 1
while [ $i -le 20 ]
do
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/ null
i=`expr $i + 1 `
done

sh add20users.sh

eg:编写一个批量删除用户的脚本程序,将上面添加的20个用户删除。

1
2
3
4
5
6
7
8
[root@localhost ~]# vim del20users.sh
#!/bin/bash
i= 1
while [ $i -le 20 ]
do
userdel -r stu$i
i=`expr $i + 1 `
done

再次查看: cat /etc/passwd 就会发现那些用户不再存在。

说了if、for 、while、语句后,就可以编写一般的系统管理任务脚本了,记得多多练习!其实除了这些Shell脚本语句外,还有好多好多,如:

case分支语句,until循环、shift移位,以及break和continue循环中断语句。大家可以查询!后续有时间我也会推出~

转载于:https://my.oschina.net/daquan/blog/487540

linux之shell脚本管理(一)相关推荐

  1. Linux之shell脚本编程

    Linux之shell脚本编程 编程介绍 shell 介绍 shell 脚本编程介绍 shell脚本命令 shell 编程基础知识 编程介绍 计算机编程的本质:输入.运算.输出 编译型语言: 程序在执 ...

  2. 【Linux】shell脚本实战-if多分支条件语句详解

    文章目录 前言 多分支语句的语法 多分支语句举例: 1. 出嫁的条件 2. 管理http服务实战脚本 3. 猜数字游戏v1版本-if版本 总结 前言 前面我们已经学习过单分支语句和双分支语句的使用. ...

  3. linux shell脚本攻略_(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤...

    今天为大家带来的内容是:(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤 本文内容主要介绍了Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤,文章 ...

  4. Linux环境Shell脚本上传下载阿里云OSS文件

    为什么80%的码农都做不了架构师?>>>    Linux环境Shell脚本上传下载阿里云OSS文件 背景 工作中由于我们项目生成的日志文件比较重要,而本地磁盘空间有限存储不了多久, ...

  5. 详解Linux交互式shell脚本中创建对话框实例教程

    详解Linux交互式shell脚本中创建对话框实例教程 本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一 ...

  6. Linux的shell脚本实战之while循环

    Linux的shell脚本实战之while循环 一.使用while循环计算 1.计算从1加到100之和 2.计算1-2+3-4+5....-100的值 二.while语句的三种方式 1.通过输入重定向 ...

  7. Linux下Shell脚本实战之监测磁盘空间

    Linux下Shell脚本实战之监测磁盘空间 一.脚本目的及要求 二.脚本内容 三.运行脚本 一.脚本目的及要求 (1) 监控/home下每各个用户目录的占用磁盘大小 (2) 监控/var/log下前 ...

  8. Linux下shell脚本之双色球摇号脚本

    Linux下shell脚本之双色球摇号脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.编写脚本Lottery.sh,模拟摇号过程 2.6位数 ...

  9. Linux下shell脚本实战之批量新建用户

    Linux下shell脚本实战之批量新建用户 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.使用提供的user.txt用户列表 2.批量新建us ...

最新文章

  1. 王贻芳院士:为什么中国要探究中微子实验?
  2. 常用对称加密算法(DES/AES)类(PHP)
  3. python现在好找工作吗-转行学Python好找工作吗?
  4. docker 全部杀掉
  5. k-means k均值聚类的弱点/缺点
  6. 小程序开发(3)-之wx.request封装
  7. jq跨域代理_jQuery中的跨域问题
  8. 计算机术语列是,计算机术语-RAM ROM
  9. leetcode python3 简单题100. Same Tree
  10. oracle从9.2.0.1升级到9.2.0.8步骤
  11. linux top 和 free 命令及 buffer和 cache 区别
  12. CSDN下载码怎么使用
  13. 13个大数据应用案例,告诉你最真实的大数据故事
  14. 基坑监测日报模板_基坑水平监测日报表
  15. ascii码与hex转换c语言,ASCII与HEX对照转换表(示例代码)
  16. 补习班停了,家长“卷向”兴趣班
  17. C语言:计算班级平均数
  18. 【java】java实现pdf根据内容定位插入图片
  19. 基于arm板linux的语音合成,基于ARM7和μCLinux的中文电子语音阅读系统的研究与应用...
  20. blender动作_Blender实现小人行走

热门文章

  1. 蓝桥杯第八届省赛JAVA真题----字母组串
  2. 排序算法(一)--桶排序、冒泡、快排(JAVA)
  3. oracle rac实例切换,RAC+单实例DG的切换
  4. linux进程map,LInux环境运行mapReduce程序
  5. 拯救者r7000怎么关闭触控板_联想拯救者R7000(2020版)上手体验,有没有AMD Yes?
  6. mysql 大分页查询优化_Mysql骚操作:优化大分页查询
  7. 计算机二级 java和web_2020年全国计算机二级WEB程序复习知识点:JavaBean
  8. java中关键字、标识符、常量、变量、数据类型
  9. java listview用法_Java ListView.setMultiChoiceModeListener方法代码示例
  10. MySQL binlog三种模式