第六章 条件测试操作与流程控制语句
第六章 条件测试操作与流程控制语句在编写shell脚本的时候,经常需要判断两个字符串是否相等,检查文件状态或者数字的测试等。shell提供了对字符串、文件、数值等内容的条件测试以及逻辑流程控制。 条件测试操作程序中的流程控制是由比较和测试语句来处理的,bash是具备多种与unix系统及特性相兼容的执行测试方法。 常用测试操作test命令,测试特定的表达式是否成立,当条件成立时,命令执行后的返回值为0,否则为非0. 格式1 test 条件表达式 格式2 [ 条件表达式 ] 常见测试类型
测试文件格式: [ 操作符 文件或目录 ] 操作符:
字符串比较格式 [ 字符串1 = 字符串2 ] [ ] 操作符:
注意: 1、字符串的“等于”比较,是为了与POSIX一致,在[]中使用"=",(也可以使用"==") POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ) 2、在"="前后各有一个空格,如果没有空格就等于赋值的关系,不是比较的关系。 3、字符串的 ‘<’ 、‘>’比较运算符,一般放在[[ ]]之中,而不是test ("[]") 4、字符串的 ‘<’ 、‘>’比较的结果,与本地的locale有关,是按照其字典序列进行比较的。 整数值比较格式 [ 整数1 操作符 整数2 ] 操作符:
逻辑测试格式 [ 表达式1 ] 操作符 [ 表达式2 ] ... 操作符:
流程控制语句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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |