加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

第六章 条件测试操作与流程控制语句

发布时间:2020-12-15 19:23:57 所属栏目:安全 来源:网络整理
导读:第六章 条件测试操作与流程控制语句 在编写shell脚本的时候,经常需要判断两个字符串是否相等,检查文件状态或者数字的测试等。shell提供了对字符串、文件、数值等内容的条件测试以及逻辑流程控制。 条件测试操作 程序中的流程控制是由比较和测试语句来处理

第六章 条件测试操作与流程控制语句

在编写shell脚本的时候,经常需要判断两个字符串是否相等,检查文件状态或者数字的测试等。shell提供了对字符串、文件、数值等内容的条件测试以及逻辑流程控制。

条件测试操作

程序中的流程控制是由比较和测试语句来处理的,bash是具备多种与unix系统及特性相兼容的执行测试方法。

常用测试操作

test命令,测试特定的表达式是否成立,当条件成立时,命令执行后的返回值为0,否则为非0.

格式1
test 条件表达式
格式2
[ 条件表达式 ]

常见测试类型

  1. 测试文件状态
  2. 字符串的比较
  3. 整数值的比较
  4. 逻辑测试

测试文件

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

操作符:

  • -d:测试是否为目录,是 则为真(Directory)
  • -e:测试目录或文件是否存在,存在 则为真(Exist)
  • -f:测试是否为文件,是 则为真(file)
  • -r:测试当前用户是否有权读取,是 则为真(read)
  • -w:测试当前用户是否有权写入,是 则为真(write)
  • -x:测试当前用户是否可执行文件,是 则为真(Excute)
  • -L:测试是否为符号链接文件,是 则为真(Link)
  • -nt:file1 -nt file2 如果file1比file2新(修改时间),则为真
  • -ot:file1 -ot file2 如果file1比file2旧(修改时间),则为真

字符串比较

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

操作符:

  • =:字符串内容相同,则为真。
  • !=:字符串内容不同,则为真。
  • -z:字符串内容为空(长度为0)则为真。
  • -n:字符串内容非空(长度非0)则为真。
  • <:str1 < str2 如果str1在本地的字典序列中排在str2之前,则为真。
  • '>':str1 > st2r如果str1在本地的字典序列中排在str2之后,则为真。

注意:

1、字符串的“等于”比较,是为了与POSIX一致,在[]中使用"=",(也可以使用"==")

POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX

2、在"="前后各有一个空格,如果没有空格就等于赋值的关系,不是比较的关系。

3、字符串的 ‘<’ 、‘>’比较运算符,一般放在[[ ]]之中,而不是test ("[]")

4、字符串的 ‘<’ 、‘>’比较的结果,与本地的locale有关,是按照其字典序列进行比较的。

整数值比较

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

操作符:

  • -eq:等于(equal)
  • -ne:不等于(not equal)
  • -gt:大于(Greater than)
  • -lt:小于(lesser than)
  • -le:小于等于(lesser or equal)
  • ge:大于等于(greater or equal)

逻辑测试

格式
[ 表达式1 ] 操作符 [ 表达式2 ] ...

操作符:

  • -a 或 &&:逻辑与,前后两个表达式都成立 则为真。
  • -o 或 ||:逻辑或,操作符两边至少有一个为真,结果为真。
  • !:逻辑否,当指定条件不成立,返回结果为真。

流程控制语句

Shell有一套自己的流程控制语句,其中包括条件语句、循环语句、选择语句等。

if条件语句

if 单分支:

当条件成立时 执行相应的操作

if 条件测试操作;
  then 命令序列
fi

执行流程:
    1、条件测试操作 为真,执行then命令序列,最后fi结束
    2、条件测试操作 为假,直接fi结束

示例:

[root@ceshi ~]# vi 60.sh        
#!/bin/bash
#判断/boot分区使用是否低于60%,低于就打印good,代表系统运行良好

use=`df -hT | grep "/boot" | awk '{print $6}' | cut -d "%" -f1`     
echo $use
if [ $use -lt 60 ];
  then
    echo "Good !!!"
fi

#注意use=`XXX`    user后面的是反撇号,不是单引号

运行:
[root@ceshi ~]# /bin/bash 60.sh 
19
Good !!!

if 双分支

当 条件成立或者条件不成立时 执行不同的操作。

if 条件测试命令;
  then 命令序列1
  else 命令序列2
fi

执行流程:
    1、如果条件测试条件为真,执行then 命令序列,最后fi结束
    2、如果条件测试条件为假,执行else 命令序列,最后fi结束

示例

[root@ceshi ~]# vi firewalld.sh        
#!/bin/bash
#判断firewalld是否在运行,如果在运行提示running,否则重启firewalld服务

systemctl status firewalld > /dev/null

if [ $? -eq 0 ];
  then
    echo "firewalld service is running!!"
  else
    systemctl restart firewalld
fi

运行:
[root@ceshi ~]# /bin/bash firewalld.sh 
firewalld service is running!!

if多分支

相当于if语句嵌套,针对多个条件执行不同操作

if 条件测试命令1;
  then
    命令序列1
elif 条件测试命令2;
  then
    命令序列2
elif ...
elif 条件测试命令n
else
  命令序列n
fi

执行流程:
    1、if 条件测试命令1为真,执行then 命令序列1,最后fi结束
    2、if 条件测试命令1为假,执行elif 条件测试命令2,
    3、elif 条件测试命令2为真,执行then 命令序列2,最后fi结束
    4、elif 条件测试命令2为假,执行elif 条件测试命令n,
    5、如果elif 条件测试命令n为真,执行then 命令序列n,最后fi结束
    6、如果elif 条件测试命令n为假,执行else下面的命令序列n,最后fi结束

示例

[root@ceshi ~]# vi num.sh        
#!/bin/bash
#测试数字2 是否比 3 5 6 8大

if [ 2>3 ];
  then
    echo "2 大于3"
elif [ 2>5 ];
  then
    echo "2 大于5"
elif [ 2 -gt 6 ];
  then
    echo "2 大于6"
elif [ 2 -gt 8 ];
  then
    echo "2 大于8"
else
  echo "2是最小的!!"
fi

运行:
[root@ceshi ~]# /bin/bash num.sh 
2是最小的!!

for循环语句

根据变量的不同取值,重复执行一组命令操作。

for 变量名 in 取值列表
do
  命令序列
done

for循环流程图,见

for循环的几种应用形式

最基本的for循环:

(传统的形式,for var in ...)

#!/bin/bash

for x in one two three four
do 
  echo $x
done

运行结果:
one
two
three
four

for循环总是接收in语句之后的某种类型的字符列表。在本例中,指定了四个英语单词,但是字符列表页可以引用磁盘上的文件,甚至文件通配符。

对目录中的文件做for循环
#!/bin/bash
for x in /var/log/*
do 
  echo $x
  #echo $(basename $x)
done

运行:
/var/log/alternatives.log
/var/log/apt
/var/log/bootstrap.log
/var/log/btmp
/var/log/dmesg
/var/log/dpkg.log
/var/log/faillog
/var/log/fsck
/var/log/lastlog
/var/log/wtmp

如果想打印结果出去前面的绝对路径信息,可以用basename;

如果只循环当前目录的文件,那么for x in *,则不会产生文件列表的路径信息的前缀。

#!/bin/bash
for x in /var/log/*
do 
  echo $(basename $x)
done

运行:
alternatives.log
apt
bootstrap.log
btmp
dmesg
dpkg.log
faillog
fsck
lastlog
wtmp
对位置参数做for循环
#!/bin/bash

for x in "$@"
do 
  echo you type ${x}
 done

for循环中使用seq产生循环次数,加上c语言形式的for循环语句

#!/bin/bash

for x in $(seq 1 5)
do 
  echo $x
 done

 echo "C语言格式的循环: for ((exp1;exp2;exp3))"
 for ((i=1; i<5; i++))
 do
   echo "i=$i"
 done

 运行:
 1
2
3
4
5
C语言格式的循环: for ((exp1;exp2;exp3))
i=1
i=2
i=3
i=4

对于固定次数的循环,可以通过seq命令来实现,就不需要变量的自增了。

while循环语句

重复测试指令的条件,只要条件为真 则反复执行对应的命令操作,直到条件为假。如果使用true作为循环条件就能够形成无限循环。

while 命令表达式
do 
  命令列表
done

示例:批量创建用户

[root@ceshi ~]# vi user.sh        
#!/bin/bash
#批量添加20个系统账户用户,依次为user1-20

i=1
while [ $i -le 20 ]
do
  useradd user$i
  echo "123456" | passwd --stdin user$i &> /dev/null
  i=`expr $i + 1`
done

运行:
[root@ceshi ~]# cat /etc/passwd 
...
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1003::/home/user3:/bin/bash
user4:x:1004:1004::/home/user4:/bin/bash
user5:x:1005:1005::/home/user5:/bin/bash
user6:x:1006:1006::/home/user6:/bin/bash
user7:x:1007:1007::/home/user7:/bin/bash
user8:x:1008:1008::/home/user8:/bin/bash
user9:x:1009:1009::/home/user9:/bin/bash
user10:x:1010:1010::/home/user10:/bin/bash
user11:x:1011:1011::/home/user11:/bin/bash
user12:x:1012:1012::/home/user12:/bin/bash
user13:x:1013:1013::/home/user13:/bin/bash
user14:x:1014:1014::/home/user14:/bin/bash
user15:x:1015:1015::/home/user15:/bin/bash
user16:x:1016:1016::/home/user16:/bin/bash
user17:x:1017:1017::/home/user17:/bin/bash
user18:x:1018:1018::/home/user18:/bin/bash
user19:x:1019:1019::/home/user19:/bin/bash
user20:x:1020:1020::/home/user20:/bin/bash

示例:批量删除用户

[root@ceshi ~]# vi user-del.sh 
#!/bin/bash
#批量删除用户user1-20

i=1
while [ $i -le 20 ]
do
  userdel -fr user$i
  i=`expr $i + 1`
done
-f:强制删除
-r:删除用户home目录

case多重分支语句

根据变量的不同取值,分别执行不同的命令操作。

case 变量值 in
  模式1)
  命令序列1
;;
  模式2)
  命令序列2
;;
  ......
*)
  默认执行的命令序列
;;
esac

示例

#!/bin/bash

case $1 in 
start)
  echo "start mysql"
;;
stop)
  echo "stop mysql"
;;
*)
  echo "usage: $0 start|stop"
;;
esac

until循环语句

根据条件执行就重复操作,直到条件成立为止。Until语句提供了与while语句相反的功能:只要特定条件为假,它们就重复循环,直到条件为真。

until 条件测试命令
do
  命令序列
done

执行流程:
    1、当until条件测试命令为假,就反复执行do 命令序列
    2、否则until条件测试命令为真,就done结束循环

示例:

#!/bin/bash

abc=1
until [ $abc -gt 10 ]
do
  echo $abc
  abc=$(( $abc + 1))
done

运行:
1
2
3
4
5
6
7
8
9
10

shift迁移语句

用于迁移位置变量,将$1 - $9依次向左传递。

例如:若当前脚本程序获得的位置变量如下:

$1=file1、$2=file2、$3=file3、$4=file4

执行一次shift命令后,各位置变量为:

$2=file2、$3=file3、$4=file4

在执行一次:

$3=file3、$4=file4

示例:传几个参数,计算这几个数字的和

[root@ceshi ~]# vi s.sh
#!/bin/bash

res=0
while [ $# -gt 0 ]
do
  res=`expr $res + $1`
  shift
done
echo "the sun is:$res"

运行:
[root@ceshi ~]# /bin/bash s.sh 1 2 3 4
the sun is:10

循环控制语句

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

在while中的示例:

while
  do
commands
commands
  break     #跳出当前循环(通常在循环体中与条件语句一起使用)
commands
commands
  done
commands
commands

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

在while中的示例:

while
  do
commands
commands
  continue  #跳出本次循环,重新开始下一次循环(通常在循环体中与条件语句一起使用)
commands
commands
  done
commands
commands

break在while中的示例

#!/bin/bash
a=0
while [ $a -lt 5 ]
do
  if [ $a = 3 ];
    then
      break   #当a=3 就跳出当前所在的循环
  fi
  echo $a
  a=`expr $a + 1`
done

运行:
0
1
2

continue在while循环中的示例

#!/bin/bash
a=0
while [ $a -lt 5 ]
do
  if [ $a = 3 ];
    then
      a=`expr $a + 1`
      continue    #如果a=3,就不打印,跳出本次循环,继续下一次循环
  fi
  echo $a
  a=`expr $a + 1`
done

运行:
0
1
2
3

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读