SHELL 中条件语句的运用 if for 条件测试语句
if条件测试语句可以让脚本根据实际情况自动执行相应的命令。从技术角度来讲,if语句分为单分支结构、双分支结构、多分支结构;其复杂度随着灵活度一起逐级上升。
if条件语句的单分支结构由if、then、fi关键词组成,而且只在条件成立后才执行预设的命令,相当于口语的“如果……那么……”。单分支的if语句属于最简单的一种条件判断结构,语法格式如图4-17所示。
图4-17 单分支的if语句
下面使用单分支的if条件语句来判断/media/cdrom文件是否存在,若存在就结束条件判断和整个Shell脚本,反之则去创建这个目录:
[root@linuxprobe ~]# vim mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
由于第5章才讲解用户身份与权限,因此这里继续用“bash 脚本名称”的方式来执行脚本。在正常情况下,顺利执行完脚本文件后没有任何输出信息,但是可以使用ls命令验证/media/cdrom目录是否已经成功创建:
[root@linuxprobe ~]# bash mkcdrom.sh
[root@linuxprobe ~]# ls -d /media/cdrom
/media/cdrom
if条件语句的双分支结构由if、then、else、fi关键词组成,它进行一次条件匹配判断,如果与条件匹配,则去执行相应的预设命令;反之则去执行不匹配时的预设命令,相当于口语的“如果……那么……或者……那么……”。if条件语句的双分支结构也是一种很简单的判断结构,语法格式如图4-18所示。
图4-18 双分支的if条件语句
下面使用双分支的if条件语句来验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线信息,要么显示主机不在线信息。这里的脚本主要使用ping命令来测试与对方主机的网络联通性,而Linux系统中的ping命令不像Windows一样尝试4次就结束,因此为了避免用户等待时间过长,需要通过-c参数来规定尝试的次数,并使用-i参数定义每个数据包的发送间隔,以及使用-W参数定义等待超时时间。
[root@linuxprobe ~]# vim chkhost.sh
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is On-line."
else
echo "Host $1 is Off-line."
fi
我们在4.2.3小节中用过$?变量,作用是显示上一次命令的执行返回值。若前面的那条语句成功执行,则$?变量会显示数字0,反之则显示一个非零的数字(可能为1,也可能为2,取决于系统版本)。因此可以使用整数比较运算符来判断$?变量是否为0,从而获知那条语句的最终判断情况。这里的服务器IP地址为192.168.10.10,我们来验证一下脚本的效果:
[root@linuxprobe ~]# bash chkhost.sh 192.168.10.10
Host 192.168.10.10 is On-line.
[root@linuxprobe ~]# bash chkhost.sh 192.168.10.20
Host 192.168.10.20 is Off-line.
if条件语句的多分支结构由if、then、else、elif、fi关键词组成,它进行多次条件匹配判断,这多次判断中的任何一项在匹配成功后都会执行相应的预设命令,相当于口语的“如果……那么……如果……那么……”。if条件语句的多分支结构是工作中最常使用的一种条件判断结构,尽管相对复杂但是更加灵活,语法格式如图4-19所示。
图 4-19 多分支的if条件语句
下面使用多分支的if条件语句来判断用户输入的分数在哪个成绩区间内,然后输出如Excellent、Pass、Fail等提示信息。在Linux系统中,read是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p参数用于向用户显示一定的提示信息。在下面的脚本示例中,只有当用户输入的分数大于等于85分且小于等于100分,才输出Excellent字样;若分数不满足该条件(即匹配不成功),则继续判断分数是否大于等于70分且小于等于84分,如果是,则输出Pass字样;若两次都落空(即两次的匹配操作都失败了),则输出Fail字样:
[root@linuxprobe ~]# vim chkscore.sh
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail"
fi
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100):88
88 is Excellent
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100):80
80 is Pass
下面执行该脚本。当用户输入的分数分别为30和200时,其结果如下:
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100):30
30 is Fail
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100):200
200 is Fail
为什么输入的分数为200时,依然显示Fail呢?原因很简单—没有成功匹配脚本中的两个条件判断语句,因此自动执行了最终的兜底策略。可见,这个脚本还不是很完美,建议读者自行完善这个脚本,使得用户在输入大于100或小于0的分数时,给予Error报错字样的提示。
如果在 if中 还 想 加 入 更多的 条件 ,就 只 需要 添加
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is henhao"
elif [ $GRADE -ge 60 ] && [ $GRADE -le 69 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail"
fi
4.3.2 for条件循环语句
for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用for循环语句再适合不过了。for循环语句的语法格式如图4-20所示。
图4-20 for循环语句的语法格式
下面使用for循环语句从列表文件中读取多个用户名,然后为其逐一创建用户账户并设置密码。首先创建用户名称的列表文件users.txt,每个用户名称单独一行。读者可以自行决定具体的用户名称和个数:
[root@linuxprobe ~]# vim users.txt
andy
barry
carl
duke
eric
george
接下来编写Shell脚本Example.sh。在脚本中使用read命令读取用户输入的密码值,然后赋值给PASSWD变量,并通过-p参数向用户显示一段提示信息,告诉用户正在输入的内容即将作为账户密码。在执行该脚本后,会自动使用从列表文件users.txt中获取到所有的用户名称,然后逐一使用“id 用户名”命令查看用户的信息,并使用$?判断这条命令是否执行成功,也就是判断该用户是否已经存在。
需要多说一句,/dev/null是一个被称作Linux黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。
[root@linuxprobe ~]# vim Example.sh
#!/bin/bash
read -p "Enter The Users Password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists"
else
useradd $UNAME &> /dev/null
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , Create success"
else
echo "$UNAME , Create failure"
fi
fi
done
执行批量创建用户的Shell脚本Example.sh,在输入为账户设定的密码后将由脚本自动检查并创建这些账户。由于已经将多余的信息通过输出重定向符转移到了/dev/null黑洞文件中,因此在正常情况下屏幕窗口除了“用户账户创建成功”(Create success)的提示后不会有其他内容。
SHELL 中条件语句的运用 if for 条件测试语句的更多相关文章
- 02: shell中的if、case、for等语句
目录: 1.1 shell中常用运算符 1.2 使用if条件语句 1.3 shell 中的for循环 1.4 shell中的while循环语句 1.5 使用case分支语句 1.1 shell中常用运 ...
- centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课
centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件.目录属性 shell数组简单用法 $( ) 和$ ...
- 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用
目录 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用 21.1 read命令键盘读取变量的值 21.1.1 read常用见用法及参数 21.2 流程控制语句if 21.2 ...
- shell中的控制流结构
shell中的控制流结构 1.if...then..else..fi语句 2.case语句 3.for循环 4.until 语句 5.while循环 6.break控制 7.continue 控制 1 ...
- shell编程系列18--文本处理三剑客之awk动作中的条件及if/while/do while/for循环语句
shell编程系列18--文本处理三剑客之awk动作中的条件及if/while/do while/for循环语句条件语句 if(条件表达式) 动作1 else if(条件表达式) 动作2 else 动 ...
- Shell中的条件测试和循环语句
1.条件测试:test或[ 如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为0 运行结果: 带与.或.非的测试命令[ ! EXPR ] : E ...
- Shell中的循环语句实例
1.for循环语句实例1.1 最基本的for循环 #!/bin/bash for x in one two three four do echo number $x done 注:" ...
- shell中条件判断if中的-z到-d的意思
shell中条件判断if中的-z到-d的意思 [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c FILE ] 如果 ...
- (二)shell中case语句、程序传参、while
2.2.6.1.case语句(1)shell中的case语句和C语言中的switch case语句作用一样,格式有差异(2)shell中的case语句天生没有break,也不需要break,和C语言中 ...
随机推荐
- caffe 的架构设计及其依赖包的解析
Caffe | Deep Learning Framework Web Classification Demos caffe(全称,Convolution Architecture For Featu ...
- WPF C# 多屏情况下,实现窗体显示到指定的屏幕内
原文:WPF C# 多屏情况下,实现窗体显示到指定的屏幕内 针对于一个程序,需要在两个显示屏上显示不同的窗体,(亦或N个显示屏N个窗体),可以使用如下的方式实现. 主要涉及到的:System.Wind ...
- MVVM讲解
一,MVVM理论知识 从上一篇文章中,我们已经知道,WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通 ...
- 在IE浏览器 使用PHPExcel导出文件时时 文件名中文乱码
1.当我们使用IE内核的浏览器下在PHPExcel报表时(谷歌.火狐浏览器正常, IE浏览器,360浏览器的兼容模式报错),会出现如下错误: 2.解决办法: 在下载文件时,对当前的浏览器进行判断, 如 ...
- SqlServer 可更新订阅队列读取器代理错误:试图进行的插入或更新已失败
原文:SqlServer 可更新订阅队列读取器代理错误:试图进行的插入或更新已失败 今天发现队列读取器代理不停地尝试启动但总是出错: 其中内容如下: 队列读取器代理在连接"Publicati ...
- Android零基础入门第2节:Android 系统架构和应用组件那些事
原文:Android零基础入门第2节:Android 系统架构和应用组件那些事 继上一期浅谈了Android的前世今生,这一期一起来大致回顾一下Android 系统架构和应用组件. 一.Android ...
- 给文件右击菜单增加7-ZIP浏览功能(用注册表设置Shell调用预览命令)
疯狂delphi delphiXE7.XE8.XE10公开课A 群号:58592705 QQ:513187410 朱建强 BAT-给文件右击菜单增加7-ZIP浏览功能 Reg给文件右击菜单增加7-ZI ...
- 解决WPF中TextBox文件拖放问题
在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...
- Docker镜像与容器命令 专题
https://yeasy.gitbooks.io/docker_practice/content/install/mirror.html docker的工作流程图: 至少需要配备三样东西去使用doc ...
- 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)
在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...