20、4 Shell脚本中的逻辑判断

在shell脚本当中很多地方都会用到逻辑判断,判断某一个数值,判断某个目录或文件,然后针对判断的结果再做一个操作,若没有判断,是无法进行一些操作的. 
例如cp一些文件,或者MV,或是删除某个文件,没有判断,写这些命令就没什么意义,也就不叫作shell脚本,可见shell脚本非常重要.

shell当中常见的逻辑判断语法
格式1:if条件;then 语句;if
格式2:if条件;then 语句;else 语句;if
格式3:if ....; then ....;elif...; then...; else...; fi 
-lt (小于)
-gt (大于)
-le (小于或等于)
-ge(大于或等于)
-eq(等于)
-ne(不等于)
&& 表示并且
|| 表示或者

#在命令行里也可以实现,不一定要写shell脚本才可以实现,只不过使用命令去实现需要使用分号.
for i in `seq 1 5`; do echo $i; done
 937d55ca90f4ae6a777e4d012a9cf7ab417.jpg
#不使用分号将会是这样的
[root@123 ~]# for i in `seq 1 5`
> do
> echo $i
> done

0134fb38d69b95779fef3975cd55e1c340f.jpg
格式1:if条件;then 语句;if
在命令行操作
a=6
if [ $a -gt 3 ]; then echo ok; fi
 d1aa487122fabfb77856e5bca3dd3c35999.jpg
说明:方括号两边需要有空格,-gt 是大于, $a大于3,那么这肯定OK的.
在脚本里写,就整理一下格式即可,然后再执行
#! /bin/bash
a=6
if [ $a -gt 3 ]
then 
    echo ok
fi

sh 04.sh 
cb4dd54f0fcc54614baad12d336846ea3a7.jpg

格式2:if条件;then 语句;else 语句;if
vim 05.sh 
#! /bin/bash
a=2
if [ $a -gt 3 ]
then
    echo ok
else
   echo nook
fi
 
sh -x 05.sh 
 f0b9389e996f3df37d269f97f564336a165.jpg
#如果$a 大于3,输出OK, 否则(else),输出nook

格式3:if ....; then ....;elif...; then...; else...; fi 
# 满足一个条件的情况
vim 06.sh
 
#! /bin/bash
a=6
if [ $a -gt 3 ]
then
    echo ">3"
elif [ $a -lt 8 ]
then
    echo "<8 && >3"
else
   echo nook
fi

#执行过程
sh -x 06.sh
 37d54e905d76b6879a478b59b701f390ba1.jpg
说明:如果$a 大于3,输出>3 ;又如果(elif)$a 小于8,输出<8 && >3
     那满足了第一个条件,$a 大于3,输出>3,后面的条件就不再执行了.
     elif 是可以使用多次的;
     lt 是小于

#所有条件都不满足的情况
vim 06.sh
#! /bin/bash
a=6
if [ $a -gt 7 ]
then
    echo ">7"
elif [ $a -lt 5 ]
then
    echo "<5 && >7"
else
   echo "nook"
fi
 
执行过程
sh -x 06.sh
 776745e1bd7337bf4def274e43523f46f54.jpg
说明:如果$a 大于7,输出>7,不满足,执行下一个条件,又如果$a 小于5,输出<5 && >7,都不满足,输出nook

文件目录属性判断
[ -f file ] 判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或者目录是否存在
[ -r file ] 判断文件是否可读
[ -w file ] 判断文件是否可写
[ -x file ] 判断文件是否可执行

[ -f file ] 判断是否是普通文件,且存在
# 判断文件是否存在,若不存就创建
vim file1.sh

#! /bin/bash
f="/tmp/linux"
if [ -f $f ]
then
    echo $f exist
else
    touch $f
Fi

#执行过程
sh -x file1.sh
 d3f3af0951f6f29e7f167c8f996959969a7.jpg
说明:if [ -f $f ]  判断/tmp/linux 是否存在,明显是不存在的,所有就touch 了这个文件
# 重新执行一次,判断文件是否存在,若存就输出结果
sh -x file1.sh
 58fe3843ca189fdc3c3461156a1cf80b64f.jpg
说明:前面不存在就touch了, 重新再执行一次肯定是存在的这个文件,那么判断输出是存在

[ -d file ] 判断是否是目录,且存在
# 判断目录是否存在,若不存在就创建
vim file2.sh 

#! /bin/bash
d="/tmp/Anna"
if [ -d $d ]
then
    echo $d exist
else
    mkdir $d
fi
 
#执行过程
sh -x file2.sh 

333724b4fa6331cb88dbeddccb99c14b348.jpg

说明:if [ -d $d ]  判断/tmp/linux 是否存在,明显是不存在的,所有就mkdir 了这个文件
#重新执行一次,判断目录是否存在,若存在就输出
sh -x file2.sh 
 12b3de1b328cedcdb978666d74e7b3da3d4.jpg
说明:前面不存在就mkdir了, 重新再执行一次肯定是存在的这个文件,那么判断输出是存在

[ -e file ] 判断文件或者目录是否存在
vim file2.sh 

#! /bin/bash
f="/tmp/Anna"
if [ -e $f ]
then
    echo $f exist
else
    mkdir $f
fi

#执行过程
 sh -x file2.sh 
 6b8f707353f12b4cbafd691db9fd75f5993.jpg
说明:-e 不管是文件或目录,是判断是否存在,不存在的话就touch
 
[ -r file ] 判断文件是否可读
vim file2.sh 
 
#! /bin/bash
f="/tmp/Anna"
if [ -r $f ]
then
    echo $f readable
fi
 
#执行
sh file2.sh 

06b76a7d017d415b8cc80257f0e1f8e8079.jpg

[ -w file ] 判断文件是否可写
vim file2.sh 
 
#! /bin/bash
f="/tmp/Anna"
if [ -w $f ]
then
    echo $f writeable
fi
 
#执行
sh file2.sh 
 ad3d85aecef57bb929591f3720c4d633290.jpg
说明:可写是针对当前root用户,若切换到user用户,那么就只有可读的权限,没有可读权限

[ -x file ] 判断文件是否可执行
vim file2.sh 
 
#! /bin/bash
f="/tmp/Anna"
if [ -x $f ]
then
    echo $f exeable
fi
 
 
#执行
sh file2.sh 
 a7d7deb5275ceb1037a660419e187480219.jpg
说明:可写是针对当前root用户,若切换到user用户,那么就只有可读的权限,没有可执行权限

判断一个目录是否存在,如果存在删除掉
vim file2.sh 
 
#! /bin/bash
d="/tmp/Anna"
if [ -d $d ]
then
   rmdir $d
fi

#执行
sh -x file2.sh 

 4720e9b1c1739dafff22f702c0eb4662ccf.jpg
#判断一个目录是否存在,如果存在就输出This is ok, 若不存在就创建
vim file2.sh 
 
#! /bin/bash
d="/tmp/Anna"
if [ -d $d ]
then
   echo "This is ok"  
else [ -d $d ]
   mkdir $d
fi
 
#执行
sh -x file2.sh 

501d271df6fad6abd39038b7739468f68a5.jpg

#! /bin/bash
f="/tmp/aaa"
if [ -f $f ] 
then 
    rm -f $f
else
    echo no
fi
还可以简写为
#! /bin/bash
f="/tmp/aaa"
[ -f $f ] && rm -f $f
判断是否存在文件aaa,如有则删除。

0c2891d41777bd004787771cd35fb24db0c.jpg
if特殊用法
if [ -z "$a" ]  表示当变量a 的值为空时会怎么样
if [ -n "$a" ]  表示当变量a的值不为空
if grep -q '123' 1.txt; then 表示如果1.txt中含有‘123’的行时会怎样
if [ ! -e file ]; then ... 表示文件不存在时会怎样
if (($a<1)); then .. 等同于 if [ $a -lt 1 ]; then...
[ ] 中不能使用 <,>, ==, !=,>=,<=这样的符号

if [ -n "$a" ]  表示当变量a的值不为空 / if [ -z "$a" ]  表示当变量a 的值为空
if [ -n "$a" ]  表示当变量a的值不为空
vim 07.sh

#!/bin/bash
n=`wc -l /tmp/123`
if [ -z "$n" ]
then
  echo error
  exit
elif [ $n -gt 100 ]
  then
     echo dfsdf
fi

说明:判断是否存在文件123,如果没有返回error;如果存在判断该文件有多少行,并与100比较,大于返回dfsdf。
sh -x 07.sh

22f9f3b2d6a9398161431d44bf315815805.jpg
还可修改为如下,先添加判断/tmp/123文件是否存在
if [ ! -f /tmp/123 ]
then
   echo "/tmp/123 not exist."
   exit
fi
n=`wc -l /tmp/123`
if [ -z "$n" ]
then
  echo error
  exit
elif [ $n -gt 100 ]
  then
     echo dfsdf
fi

(其中
if [ -z "$n" ]
then
  echo error
  exit
可不再做判断
直接改为
n=`wc -l /tmp/123`
if [ $n -gt 100 ]
  then
     echo dfsdf
fi

ee6f6454b5c9173e484fac654c0a79e8f85.jpg
if [ -n 01.sh ]; then echo ok; else echo "01.sh is null"; fi
 5a765e8233af791abc3b10fde4e177e44ca.jpg
说明: 判断01.sh 是否为空,不为空 ,输出ok 
if [ -n "$b" ]; then echo $b; else echo "b is null"; fi

01e5d613d85a44e3a09fc387426d88689a6.jpg

说明:判断b的值是否为空(由于没有赋值此处为空)

# if [ -z "$a" ]  表示当变量a 的值为空 
if [ -z "$b" ]; then echo no null; fi
no null
 
if grep -wq 'mysql' /etc/passwd; then echo "mysql exist"; fi

de3af674fa1e470ebb0b6309660d263a0e3.jpg

说明:查看是否有mysql用户, grep -wq中w表示之后将mysql作为一个词来查找,q表示忽略显示查找过程信息
if ! grep -wq 'mysql' /etc/passwd; then useradd mysql; fi
说明:如果没有mysql用户,则使用useradd命令添加mysql用户

if [ ! -e file ]; then ... 表示文件不存在时会怎样
vim 08.sh
 
#! /bin/bash
if [ ! -f /tmp/Annalinux ]
then
    echo "No such file or directory"
    exit
fi
if [ -f /tmp/Annalinux ]
then
    echo "This is file"
    exit
fi
 
sh -x 08.sh 
 5b8b644c98078d49ee9dde48646308bcd9e.jpg
说明: 先判断/tmp/Annalinux 文件是否存在,如果不存在,输出 No such file or directory。并退出
      如果存在,输出This is file,并退出.
       ! -F 表示不存在
       -f 表示存在
       ! -f  和 -f  意思相反

cace判断
case 逻辑判断
说明:这个脚本的目的是让用户输入一个数字,然后用这个脚本去判断用户输入的数字的一个范围

vim case.sh
 
#! /bin/bash
read -p " Please input a number: " n
if [ -z "$n" ]                         //判断 $n是否为空, 为空的话,说明用户没有输入数字
then 
     echo "Please input a number."     //那么就提示请输入数字
     exit 1                            //然后退出来,返回一个数值 1                
fi
n1=`echo $n |sed 's/[-0-9]//g'`        //判断输入的是否是纯数字,echo 出来后,做一个特殊操作,使用sed 把所有
                                         的数字 0-9 清空, $n1 这个变量就为空了
if [ ! -z $n1 ]                        // 当变量不为空时,说明输入的不是数字,不合法,则提示继续输入数字
                                          当变量为空时继续往下执行,说明输入的是数字
then
     echo "Please input a number."     //继续提示输入数字
     exit 1                            //继续退出来,返回一个数值 1
#elif [ $n -lt 0 ] || [ $n -gt 100 ]
#then 
#     echo "Then number range is 0-100."
#     exit 1
fi
if [ $n -lt 60 ]
then 
      tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then 
      tag=2
elif [ $n -ge 80 ] && [ $n -lt 90 ]
then 
      tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
      tag=4
else
      tag=0
fi
case $tag in
        1)
        echo " 不及格"
        ;;
        2)
        echo "及格"
        ;;
        3)
        echo "良好"
        ;;
        4)
        echo "优秀"
        ;;
        *)
        echo "The number range is 0-100."
        ;;
esac
 
# read -p " Please input a number: "n
说明 n 作为捕获一个变量的名字,用户输入什么数字,那么这个n 就会赋值什么数字,这就是read -p 的作用
(注意清空中文注释)
 
演示:
read -p " Please input a number: " n
echo $n

a210711dccd0acd1f57c0953d33d0abb405.jpg

#执行,输入数字90
sh -x case.sh
+ read -p ' Please input a number: ' n
 Please input a number: 90
+ '[' -z 90 ']'        //判断 90 变量是否存在
++ sed 's/[-0-9]//g'   // $n1 清空 
++ echo 90
+ n1=                  //$n1 为空
+ '[' '!' -z ']'       // 判断是否不为空,不为空说明正常,往下匹配
+ '[' 90 -lt 60 ']'
+ '[' 90 -ge 60 ']'
+ '[' 90 -lt 80 ']'
+ '[' 90 -ge 80 ']'
+ '[' 90 -lt 90 ']'
+ '[' 90 -ge 90 ']'
+ '[' 90 -le 100 ']'
+ tag=4               //匹配到了第4个条件
+ case $tag in
+ echo $'\344\274\230\347\247\200'
优秀
 4bee551bb3c3ba9b3be589bbeb8bc013914.jpg
# 执行,输入非数字,就会提示请输入数字
sh -x case.sh 
+ read -p ' Please input a number: ' n
 Please input a number: gsagas
+ '[' -z gsagas ']'        //判断 gsagas 变量是否存在
++ sed 's/[-0-9]//g'       //清空$n1 所有数字
++ echo gsagas
+ n1=gsagas                //$n1不为空,所以输入的不是数字有问题
+ '[' '!' -z gsagas ']'
+ echo 'Please input a number.' 
Please input a number.       //提示请输入数字
+ exit 1

97b7efca8ac458264c3e824b0ce1566bebc.jpg
for循环
语法:for 变量名 in 条件; do …; done
案例1
1+2+3..+100的和
sum 第一次作为变量的时候,是0;当进入for循环里面的时候,每运算一次,sum变量就会改变一次,直至$i 结束;最后输出结果 $sum
在做加减法的时候,[ ] 方括号里面不需要加空格

#!/bin/bash
sum=0
for i in `seq 1 100`
#seq  1到100个数字
do
    sum=$[$sum+$i]
    echo $i
done
echo $sum

for循环案例2
文件列表循环
列出所有 etc目录下的子目录

#!/bin/bash
cd /etc/
for a in `ls /etc/`
do
    if [ -d $a ]
    then
       ls -d $a
    fi
done

for a in `seq 1 3`; do echo $a; done 
for a in 1 2 3; do echo $a; done
 d5a0aeb780224ed67ab2c7a3c36a5b367b4.jpg
for 循环的时候会以 空格 或者 回车做为分隔符

while循环
语法 while 条件; do … ; done
案例1
每隔1分钟检查一下系统负载,当系统的负载大于10的时候,发一封邮件(监控脚本)
最小单元是任务计划 cron

#!/bin/bash
while :
# 冒号 : 表示死循环的意思,或者1,或者 true都是死循环
do
    load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
    if [ $load -gt 10 ]
    then
           /usr/local/sbin/mail.py xxx@163.com "load high" "$load"
    fi
    sleep 30
#休眠30秒,因为检查系统负载,不需要一直去检查,过一会再看
done

sh -x while1.sh 

2e978afee37159c347b8456078366183482.jpg

若想这种脚本不意外的终止,可以打开screen,在screen跑脚本

知识点
w //查看系统负载 ;
uptime 可以直接显示 w 系统负载的第一行,就可以省去 head -1
head -1 //取第一行
awk -F 'load average: ' '{print $2}' // 以'load average: '分隔,输出第二段
cut -d . -f1 // 以 . 分隔 取第一段
while循环案例2
在循环过程过,需要用户输入一个数字;输入的不是数字,是数字,输入为空;回应相应的结果

#!/bin/bash
while :
do
    read -p "Please input a number: " n
    if [ -z "$n" ]
    then
        echo "you need input sth."
        continue
#continue 重新回到循环
    fi
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
        echo "you just only input numbers."
        continue
    fi
    break
#break  退出循环
done
echo $n

break跳出循环
break 常用于循环语句中
跳出整个循环语句,直接结束所有循环

#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i -eq 3 ]
#比较数字,用-eq ;若是比较的是字符串,那需要用 ==
    then
        break
    fi
    echo $i
done
echo aaaaaaa

sh -x berak.sh

48ee6ff12fe2127acf52bd81f1c8c26353a.jpg

sh berak.sh

71c676b3c38a5583ff0ac26e5db2af306ed.jpg
continue结束本次循环
忽略continue之下的代码,直接进行下一次循环

#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i -eq 3 ]
    then
        continue
    fi
    echo $i
done
echo $i

sh continue.sh

 36ca608998168d2c8c54427750ccf09ac5f.jpg
exit退出整个脚本
exit直接结束退出整个脚本
可以定义退出的数值,可以用于确定脚本运行到什么地方的时候,结束

#!/bin/bash
for i in `seq 1 5`
do
    echo $i
    if [ $i -eq 3 ]
    then
        exit
    fi
    echo $i
done
echo aaaaaaa

sh exit.sh
528d847a11c2bcc8f85a785c847192f3df1.jpg

扩展
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html
 

转载于:https://my.oschina.net/u/3867322/blog/2051212

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值