条件测试和结构化语句

条件测试

if语句

for循环语句

调试:

echo

bash -x

set -x

set +x

set -e 命令行报错就退出shell

条件测试操作

test命令

  • 测试特定的表达式是否成立,当条件成立时,测试语句的返回值为0,否则为其他数值
  • 格式1:test 条件表达式
  • 格式2:[ 条件表达式 ] 至少应有一个空格

常见的测试类型

  • 测试文件状态
  • 整数值比较
  • 字符串比较
  • 逻辑测试

文件测试

格式:[ 操作符 文件或目录 ]

常用的测试操作符

  • -d:测试是否为目录(Directory)
  • -e:测试目录或文件是否存在(Exist)
  • -f:测试是否为文件(File)
  • -s: 测试文件存在且内容非空(仅有1个空格也是非空)
  • -r:测试当前用户是否有权限读取(Read)
  • -w:测试当前用户是否有权限写入(Write)
  • -x:测试当前用户是否有权限执行(eXcute)
[[email protected] ~]# [  -d /etc/vsftpd  ]
[[email protected] ~]# echo $?
0 //返回0表示条件成立
[[email protected] ~]# [  -d /etc/hosts  ]
[[email protected] ~]# echo $?
1 //返回1表示条件不成立
[[email protected] ~]# [ -e /media/cdrom ] && echo "YES"
YES //逻辑与,“而且”的意思

整数值比较(传统方法)

  • 格式:[ 整数1 操作符 整数2 ]

常用的测试操作符

-eq:等于(Equal)

-ne:不等于(Not Equal)

-gt:大于(Greater Than)

-lt:小于(Lesser Than)

-le:小于或等于(Lesser or Equal)

-ge:大于或等于(Greater or Equal)

[[email protected] ~]# who | wc -l
7
[[email protected] ~]# [ $(who | wc -l) -gt 5 ] && echo "Too many." // 用户数是否 > 5
Too many. 
[[email protected] ~]# [ $(who | wc -l) -ge 10 ] && echo "> = 10."          //用户数是否 >= 10
[[email protected] ~]# FreeCC=$(free -m | grep Mem: | tr -s ‘ ’ |cut -d‘ ’ -f4)
[[email protected] ~]# [ $FreeCC -lt 1024 ] && echo ${FreeCC}MB        //空闲内存是否 < 1024MB
864MB

双圆括号整数值比较(推荐方法)

  • 格式(( 整数1 操作符 整数2 ))
[[email protected] ~]# (( 10+2 > 10-2 )) && echo ok || echo no
ok
[[email protected] ~]# a=10
[[email protected] ~]# ((a>20)) && echo ok || echo no     //变量加不加$都可以
no
[[email protected] ~]# ((a<20)) && echo ok || echo no 
ok
[[email protected] ~]# ((a==20)) && echo ok || echo no     //注意这里是两个=,一个=是赋值
no
[[email protected] ~]# ((a!=20)) && echo ok || echo no    ///不等于只能用一个=
ok

字符串比较(传统方法)

  • 格式1:[ 字符串1 = 字符串2 ]

[ 字符串1 != 字符串2 ]

  • 格式2:[ -z 字符串 ]

常用的测试操作符

=:字符串内容相同

!=:字符串内容不同,! 号表示相反的意思

-z:字符串内容为空

-n:字符串非空

[[email protected] ~]# echo $LANG   
zh_CN.UTF-8
[[email protected] ~]# [ $LANG !=  "en.US" ] && echo  "Not en.US"     //测试当前语言环境
Not en.US
[[email protected] ~]# read -p “是否覆盖现有文件(yes/no)?"  ACK
是否覆盖现有文件(yes/no)?yes
[[email protected] ~]# [ $ACK = "yes" ] && echo "覆盖"       //测试读入的字符串是否为 yes
覆盖

字符串比较时建议加上双引号

[[email protected] ~]# a=123
[[email protected] ~]# [ -z $a ] && echo ok || echo no
no
[[email protected] ~]# a=
[[email protected] ~]# [ -z $a ] && echo ok || echo no
ok
[[email protected] ~]# [ -n $a ] && echo ok || echo no                 
ok
[[email protected] ~]# [ -n "$a" ] && echo ok || echo no                    //和预计结果不一致
no
[[email protected] ~]# a="abc 123"
[[email protected] ~]# [ -z $a ] && echo ok || echo no
-bash: [: abc: binary operator expected                              //语法错误
no
[[email protected] ~]# [ -z "$a" ] && echo ok || echo no
no
[[email protected] ~]# [ "$a" = "abc 123" ] && echo ok || echo no
ok

双方括号字符串比较(推荐方法)

  • 格式: [ [ 字符串1 = 字符串2 ]]

可以解决变量中带空格的问题

[[email protected] ~]# a="abc 123"
[[email protected] ~]# [ $a = "abc 123" ] && echo ok || echo no  
-bash: [: too many arguments
no
[[email protected] ~]# [[ $a = "abc 123" ]] && echo ok || echo no
ok

双方括号字符串比较(推荐方法)

可以使用通配符

[[email protected] ~]# cat test.sh
#!/bin/bash
[[ $1 = ??? ]] && echo ok || echo no   //匹配字符是任意三个字符的
[[email protected] ~]# ./test.sh ab
no
[[email protected] ~]# ./test.sh abc
ok
[[email protected] ~]# cat test.sh
#!/bin/bash


[[ $1 = a* ]] && echo ok || echo no    //匹配字符是a开头的
[[email protected] ~]# ./test.sh bbba
no
[[email protected] ~]# ./test.sh abb
ok

双方括号字符串比较(推荐方法)

可以使用通配符

[[email protected] ~]# cat test.sh
read -s -p "please input password: " pass
[[ $pass = ???* ]] && echo passwd is ok || echo passwd too short
//判断密码的长度至少要3位

逻辑测试

  • 格式1:[ 表达式1 ] &&或|| [ 表达式2 ] ...
  • 格式2:[ 表达式1 -a或-o 表达式2 ] ...

常用的测试操作符

-a或&&:逻辑与,“而且”的意思

前后两个表达式都成立时整个测试结果才为真,否则为假

-o或||:逻辑或,“或者”的意思

操作符两边至少一个为真时,结果为真,否则结果为假

!:逻辑否

当指定的条件不成立时,返回结果为真

[[email protected] ~]# [ -d /etc/passwd -a -f /etc/fstab ] && echo ok || echo no
no
[[email protected] ~]# [ -d /etc/passwd -o -f /etc/fstab ] && echo ok || echo no 
ok
[[email protected] ~]# [ ! -d /etc/passwd ] && echo ok || echo no                  
ok
[[email protected] ~]# (( ! 10 > 5 )) && echo ok || echo no
no

if语句的结构

单分支结构

双分支结构

多分支结构

if语句应用示例

单分支if语句

检查httpd服务是否开启

[[email protected] ~]# cat test.sh
#!/bin/bash
If ! service httpd status &> /dev/null
then
           service httpd start
fi

双分支if语句

判断目标主机是否存活,显示检测结果

[[email protected] ~]# cat pinghost.sh
#!/bin/bash
if ping -c 3 -i 0.2 -w 2 $1 &> /dev/null
then
 echo "Host $1 is up."
else
 echo "Host $1 is down."
fi
[[email protected] ~]# ./pinghost.sh 192.168.4.11
Host 192.168.4.11 is up.
[[email protected] ~]# ./pinghost.sh 192.168.4.13
Host 192.168.4.13 is down.

双分支if语句

#!/bin/bash

if rpm -q sysstat &> /dev/null
then
 echo "已安装 `rpm -q sysstat`"
else
 echo "未安装,尝试自动安装"
    RHEL_DIR="/media/cdrom/Server/"
 if [ -d $RHEL_DIR ]
 then
 cd $RHEL_DIR
        rpm -ivh sysstat-*.rpm && echo "安装完成。"
 else
 echo "错误:无法访问光盘目录:$RHEL_DIR"
 fi
fi

多分支if语句

判断分数范围,分出优秀、合格、不合格三档

#[[email protected] ~]# cat gradediv.sh   判断分数所在区间,给出不同的分档结果
#!/bin/bash
read -p "请输入您的分数(0-100):" GRADE
if (( $GRADE >= 85 )) && (( $GRADE <= 100 ))
then
 echo "$GRADE 分!优秀"
elif (( $GRADE >= 70 )) && (( $GRADE <= 84 ))
then
 echo "$GRADE 分,合格"
else
 echo "$GRADE 分?不合格”
fi
[[email protected] ~]# ./gradediv.sh
请输入您的分数(0-100):89
89 分!优秀

exit命令

默认情况下shell脚本以脚本中最后一条命令的退出状态退出,exit后的命令不会被执行,马上 退出脚本

  • exit n n是0-255的退出状态数值,不写n默认为0
#!/bin/bash
name=sxkj
if [[ $1 = $name ]]
 then
 echo "不能创建$name这个用户"
 exit 1
 else
 useradd $1 && echo 123 | passwd --stdin $1 &> /dev/null
fi
echo "用户$1已经创造完成"

for语句的结构

已知循环次数

读取不同的变量值,用来逐个执行同一组命令

for语句

  • for i in 的各种用法
  • for i in "file1" “file2” “file3”
  • for i in /boot/*
  • for i in /etc/*.conf
  • for i in $(seq -w 10)
  • for i in {1..10}
  • for i in $( ls )
  • for I in $(<file)
  • for i in “[email protected]” #取所有位置参数,可简写为for i

for语句C语言语法

bash shell支持C式for循环

  • for (( i=1; i<10; i++ ))

根据脚本输入的参数创建任意个文件

#!/bin/bash
j=$1
for ((i=1; i<=j; i++))
do
 touch file$i && echo file $i is ok
done

for语句应用示例

编写脚本清空所有arp缓存记录

#!/bin/bash
for i in $(arp | tail -n +2 | tr -s ‘ ‘ | cut -d‘ ‘ -f1)
do
   arp -d $i
done

产生十个随机数

[[email protected] ~]# for i in {0..9}; do echo $RANDOM;done
[[email protected] ~]# for i in $( seq 10); do echo $RANDOM;done

倒数5秒

#!/bin/bash
echo "准备倒数5秒"
for i in $(seq 5 -1 1)
do
 echo -en "$i“
 sleep 1
done
echo -e "开始"
#!/bin/bash
echo "准备倒数5秒"
for i in $(seq 5 -1 1)
do
 echo -en "$i\b"
 sleep 1
done
echo "开始"

批量添加用户

用户名存放在users.txt文件中,每行一个

[[email protected] ~]# cat uaddfor.sh
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
 useradd $UNAME
 echo "123456" | passwd --stdin $UNAME
done

初始密码均设为123456

[[email protected] ~]# ./uaddfor.sh
[[email protected] ~]# tail -3 /etc/passwd
chenye:x:1011:1011::/home/chenye:/bin/bash
dengchao:x:1012:1012::/home/dengchao:/bin/bash
zhangjie:x:1013:1013::/home/zhangjie:/bin/bash

根据位置参数批量添加用户

#!/bin/bash
for i in [email protected] #可替换成for i
do
 useradd $i && echo user $i is ok
 echo 123456 | passwd --stdin $i &> /dev/null
done
[[email protected] ~]# ./myuseradd.sh aa bb cc dd
user aa is ok
user bb is ok
user cc is ok
user dd is ok

根据IP地址检查主机状态

IP地址存放在ipadds.txt文件中,每行一个

[[email protected] ~]# cat /root/ipadds.txt
192.168.4.11
192.168.4.110
192.168.4.120
[[email protected] ~]# cat chkhosts.sh
#!/bin/bash
HLIST=$(cat /root/ipadds.txt) #从列表文件读取IP地址
for IP in $HLIST
do
 ping -c 2 -i 0.2 -w 1 $IP &> /dev/null
 if (($?==0)) ; then
 echo "Host $IP is up."
 else
 echo "Host $IP is down." #嵌套if语句判断连通性
 fi
done

使用ping命令检测各主机的连通性

[[email protected] ~]# ./chkhosts.sh
Host 192.168.4.11 is up.
Host 192.168.4.110 is down.
Host 192.168.4.120 is up.

循环控制语句

break语句

在for、while、until等循环语句中,用于跳出当前所在的循环体,执行循环体后的语句

continue

在for、while、until等循环语句中,用于跳过循环体内余下的语句,重新判断条件以便执行下一次循环

break和continue语句应用示例

分析下列两个脚本的显示结果

#!/bin/bash
for i in `seq 6`
do 
if ((i % 2 == 0 ))
then
 break;
fi
echo $i;
done
#!/bin/bash
for i in `seq 6`
do
if ((i % 2 == 0 ))
 then
 continue;
 fi
echo $i;
done

案例

实验案例1

使用条件测试完成下列任务

测试/分区磁盘空间,小于10%,显示“一切正常”,否则显示“当前的磁盘空间是磁盘空间% 警告”

统计当前系统的登陆用户,登陆用户小于3个,显示“一切正常”,否则显示“登陆用户已经有:个数”

测试当前主机eth0的网卡入站和出站流量,只要两个都大于200MiB,就显示“警告”;

当内存空闲空间小于内存的5%时,显示“内存不足”,否则显示“当前空闲内存是:内存空闲数值”

实验案例2

判断内核版本,如果大于2.4,显示“内核版本:版本,否则显示“内核版本太低,无法继续”

检查vsftpd服务是否开启,显示效果如下

[[email protected] ~]# test.sh           
警告: vsftpd 服务没有启动,准备启动
为 vsftpd 启动 vsftpd:                                    [确定]
[[email protected] ~]# test.sh           
监听地址: 0.0.0.0:21
进程PID: 10478
[[email protected] ~]# yum remove vsftpd
[[email protected] ~]# test.sh
vsftpd服务不存在

实验案例3

数字范围识别,输入整数得分判断分数范围

90分到100分显示成绩优秀

61分到89分显示成绩合格

60分显示及格万岁

60分以下显示你需要补考

大于100分小于0分显示输入错误

[[email protected] test]# ./test.sh 78
成绩合格
[[email protected] test]# ./test.sh 93
成绩优秀
[[email protected] test]# ./test.sh 101
输入错误,请输入0-100间的整数
[[email protected] test]# ./test.sh 60
及格万岁
[[email protected] test]# ./test.sh 31
你需要补考

实验案例4

编写我是歌手脚本

要求判断名单文件是否存在

显示效果如下

[[email protected] test]# bash lucky.sh
欢迎来到我是歌手第2季,还有3位参赛歌手,请按任意键开始选择
****这次为大家献唱的是谁呢?我们一起倒数3秒钟****
3 2 1 会是谁呢?
有请歌手‘丝丝‘登台
还有位2位歌手,下次又会是谁呢,O(∩_∩)O哈哈~
[[email protected] test3]# bash lucky.sh
欢迎来到我是歌手第2季,还有2位参赛歌手,请按任意键开始选择
****这次为大家献唱的是谁呢?我们一起倒数3秒钟****
3 2 1 会是谁呢?
有请歌手‘龙龙‘登台
只剩下1位压轴歌手啦,万众瞩目的一天就要来到了,(*^__^*) 嘻嘻……
[[email protected] test3]# bash lucky.sh
没得选了,就是有歌坛赵本山之称的‘安安‘啦,我是歌手下季将重新开始哦

实验案例4

编写脚本利用for循环显示出相应的位置参数。

[[email protected] ~]# ./test.sh 11 
脚本有1个参数
$1 is 11
[[email protected] ~]# ./test.sh aa bb
脚本有2个参数
$1 is aa
$2 is bb
[[email protected] ~]# ./test.sh aa bb cc
脚本有3个参数
$1 is aa
$2 is bb
$3 is cc
[[email protected] ~]# ./test.sh 
脚本没有接参数

实验案例5

查找用户的PATH环境变量中每个目录下有多少个文件

要求判断目录是否存在

[[email protected] ~]# ./test.sh

/usr/lib/qt-3.3/bin - 0

/usr/local/sbin - 0

/usr/local/bin - 0

/sbin - 269

/bin - 111

/usr/sbin - 317

/usr/bin - 1411

/root/bin is not exist

实验案例6

查找UID大于等于500小于等于60000的用户,检查他们在“/tmp”目录中拥有的子目录或文件数量,如果超过10个,则列出具体个数及对应的用户帐号

[[email protected] ~]# ./test.sh
aa have 41 files
bb have 110 files

编写脚本统计1000以内个位是十位2倍的数字的个数(例如24)

实验案例7

统计/usr/share/doc目录下所有后缀名是png文件的占用空间总和。

利用for循环实现累加,显示效果如下图所示

[[email protected] ~]# ./test.sh
all png files total size is 2540k

计算1000以内所有偶数的总和

建议使用for循环

实验案例9

编写add.sh脚本实现批量创建帐户,脚本要求如下:

提示输入用户名前缀和用户数目

每次创建的用户最多只能是10个,超过10个用户,就不要新建用户并且要报警显示“最多只能同时新建10个用户”然后退出脚本

每新建一个用户,就显示“新用户用户名创建成功”。如果新建用户失败,就显示“新用户用户名创建失败”。密码123最后要显示新建的用户总数是“一共新建的用户数:数目”

[[email protected] ~]# bash add.sh
请输入用户名的前缀: stu
请输入用户的数目: 15
最多只能同时新建10个用户
[[email protected] ~]# bash add.sh
请输入用户名的前缀: sxkj
请输入用户的数目: 2
用户sxkj1已经创建成功
用户sxkj2已经创建成功
一共创建的用户数:2个

实验案例10

编写del.sh脚本实现批量删除用户,脚本要求如下:

提示输入需要删除的用户名前缀,如果用户名前缀为空或者空格,就显示“请输入合法用户名前缀”,然后退出脚本,每删除一个用户,要显示“用户用户名 已经成功被删除”。如果没有可以删除的用户,就显示“以用户前缀开头的用户不存在”。最后要显示删除的用户总数是“一共删除的用户数:数目”

注意不能删除管理员或者系统用户(UID小500或者大于60000)

[[email protected] ~]# add.sh
请输入用户名的前缀: rr
请输入用户的数目: 2
用户rr1已经创建成功
用户rr2已经创建成功
一共创建的用户数:2个
[[email protected] ~]# del.sh
请输入需要删除的用户名前缀:
请输入合法的用户名前缀
[[email protected] ~]# del.sh
请输入需要删除的用户名前缀:
请输入合法的用户名前缀
[[email protected] ~]# del.sh
请输入需要删除的用户名前缀: r
root是系统用户不能删除
rpc是系统用户不能删除
rtkit是系统用户不能删除
rpcuser是系统用户不能删除
用户rr1已经被成功删除
用户rr2已经被成功删除
一共删除的用户数:2个

原文地址:https://www.cnblogs.com/qluzzh/p/10306301.html

时间: 2024-10-10 06:02:39

条件测试和结构化语句的相关文章

shell基础 变量 条件测试 判断结构

Top NSD ENGINEER DAY02 案例1:Shell脚本的编写及测试 案例2:重定向输出的应用 案例3:使用特殊变量 案例4:编写一个判断脚本 案例5:编写一个批量添加用户脚本 1 案例1:Shell脚本的编写及测试 1.1 问题 本例要求两个简单的Shell脚本程序,任务目标如下: 编写一个面世问候 /root/helloworld.sh 脚本,执行后显示出一段话“Hello World!!” 编写一个能输出系统信息的 /root/sysinfo 脚本,执行后依次输出当前红帽系统的

软件测试概述、结构化测试

一.软件测试的目的 是在最小的成本和最短的时间内,通过设计良好的测试规程和测试用例,系统地发现不同类别的错误. 二.软件测试的基本原则 设计好的测试用例.不可能进行穷举测试.尽早开展测试.重点测试.定期进行检验与修正测试用例,并增加新的测试用例.测试依赖于系统环境.测试用例应该包含合理和不合理的输入条件. 测试过程模型 V模型特点:1.对应瀑布模型的变种(自下到上)线性关系 2.有局限性,在于不能体现"尽早地和不断地进行软件测试"的原则 3.仅仅把测试过程作为在需求分析.概要设计.详细

数据库技能实战进阶之常用结构化sql语句(上)

常用的结构化查询语言主要分为数据定义语言(DDL).数据操作语言(DML).数据控制语言(DCL)和数据查询语言(DQL).特别在关系型的数据库例如(mysql.mariadb. percona.DB2.Oracle.SQL server)等都是采用共同的SQL语句来实现增删改查等数据的管理.本文会针对以下的四种类型的结构化SQL来进行介绍. DDL 数据定义语言  create     drop     alter DML 数据操作语言  insert    delete   update D

结构化查询语句格式

数据库(DataBase):存放数据的仓库;存放的是一张一张的表,特别像Excel,都以表格形式存放数据,可以创建多张表 常见的数据库: sqlite ,access, MySQL,SqlServer, Oracle; 为什么要用数据库; 1.文件读写,归档读取数据需要一次把数据全部读出来,占内存 2.数据库查找数据效率很高,体现在查找数据,数据修改(增删改查) SQL(structured Query Language )结构化查询语句,用于对数据库的操作语句(增删改查) SQL语句不区分大小

Shell条件测试语句及三种if语句

7 - Shell_条件操作测试及if语句 要使Shell脚本程序具备一定的"智能",面临的第一个问题就是如何区分不同的情况以确定执行何种操作.例如,当磁盘使用率超过95%发送警告:当备份目录不存在时能够自动创建:当源码编译程序的配置失败则不再继续安装等. Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0,表示成功,值为其他时,表示失败. 使用专门的测试工具-test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0为成立) 使用te

shell条件测试,运算符,选择结构,for循环结构

一.shell条件测试      man bash  //查看帮助 条件测试的命令 test 选项 文件名或目录名 或 [ 选项 文件名或目录名 ] 例: [ -e /etc/passd ] 文件状态 -f              //判断是不是文件,是文件为真 -d //判断是不是目录,是目录为真 -e //判断是不是存在,存在为真 -r //判断是否可以阅读,可以阅读为真 -w //判断是否可写,可写为真 -x //判断是否可执行,可执行为真 -l //判断是否为链接,是链接为真 数值比较

SQL结构化查询语句

SQL结构化查询语句 SQL定义了查询所有关系型数据库的规则. 1.通用语法 SQL语句可以单行或者多行书写,以分号结尾 可以使用空格和缩进增强可读性 不区分大小写,但是关键字建议大写 3种注释 注释内容:多行注释/*;-- 注释内容 2.SQL分类 DDL(Date Definition Language)数据定义语言 用来定义数据库对象:数据库.表.列等,包括关键字:create,drop.alte DML(Data Manipulation Language)数据操作语言,增删改 用来对数

Shell脚本的条件测试和if条件语句使用

博文目录一.条件测试操作1.文件测试:2.整数值比较:3.字符串比较:4.逻辑测试:二.使用if条件语句1.单分支if语句2.双分支if语句3.多分支if语句 一.条件测试操作 要使Shell脚本程序具备一定的"智能",面临的第一个问题就是如何区分不同的情况以确定执行何种操作.Shell环境根据命令执行后的返回状态值(¥?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常.使用专门的测试工具--test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立

九、while 条件循环语句、case 条件测试语句、计划任务服务程序

4.3.3 while条件循环语句 while条件循环语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于for循环语句中有目标.有范围的使用场景.while循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为真就继续执行,为假就结束循环.while语句的语法格式如图4-21所示. 图4-21  while循环语句的语法格式 接下来结合使用多分支的if条件测试语句与while条件循环语句,编写一个用来猜测数值大小的脚本Guess.