欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

9.14任务

程序员文章站 2022-05-07 10:53:55
...

20.5 shell脚本中的逻辑判断

逻辑判断格式大抵三种。

  1. if condition; then statement; fi
  2. if condition; then statement; else statement; fi

  3. if condition; then statement; elif condition; then statement; else statement; fi

逻辑判断的开始为if关键字,结束为fi关键字,可以写成一行由分号分隔,也可以按c语言AStyle标准写为多行。

逻辑条件有几种,比如给变量a赋值立即数5,然后判断a是否大于3,就可以使用逻辑条件[ $a -gt 3 ] 。

要注意这里的格式,中括号括起来的语句是逻辑条件的主体,比较者、被比较者、逻辑运算符和中括号两两之间都必须要有空格分隔。

格式1:

#!/bin/bash
a=5
if [ $a -gt 3 ];
then
        echo ok;
fi

格式2:

#!/bin/bash
a=1
if [ $a -gt 3 ];
then
        echo ok;
else
        echo not ok;
fi
[email protected]:~/shell_script# sh -x if1.sh 
+ a=1
+ [ 1 -gt 3 ]
+ echo not ok
not ok

格式3:

#!/bin/bash
a=5
if [ $a -gt 1 ];
then
        echo ">1";
elif [ $a -lt 6 ]
then
        echo "< 6 && > 1"
else
        echo not ok;
fi
[email protected]:~/shell_script# sh -x if1.sh 
+ a=5
+ [ 5 -gt 1 ]
+ echo >1
>1
#!/bin/bash
a=5
if [ $a -lt 1 ];
then
        echo "<1";
elif [ $a -lt 6 ]
then
        echo "< 6 && > 1"
else
        echo not ok;
fi
[email protected]:~/shell_script# sh -x if1.sh 
+ a=5
+ [ 5 -lt 1 ]
+ [ 5 -lt 6 ]
+ echo < 6 && > 1
< 6 && > 1
#!/bin/bash
a=7
if [ $a -lt 1 ];
then
        echo "<1";
elif [ $a -lt 6 ]
then
        echo "< 6 && > 1"
else
        echo not ok;
fi
[email protected]:~/shell_script# sh -x if1.sh 
+ a=7
+ [ 7 -lt 1 ]
+ [ 7 -lt 6 ]
+ echo not ok
not ok

整数逻辑判断表达式如下

  • -eq     等于,                              [ "$a" -eq "$b" ] 
  • -ne     不等于,                           [ "$a" -ne "$b" ] 
  • -gt      大于,                              [ "$a" -gt "$b" ] 
  • -ge     大于等于,                       [ "$a" -ge "$b" ]
  • -lt       小于,                              [ "$a" -lt "$b" ] 
  • -le      小于等于,                        [ "$a" -le "$b" ] 
  • <  小于(需要双括号),              (("$a" < "$b")) 
  • <= 小于等于(需要双括号),       (("$a" <= "$b")) 
  • >  大于(需要双括号),              (("$a" > "$b")) 
  • >= 大于等于(需要双括号),       (("$a" >= "$b"))

在此处双引号也可以省略。

也可以使用&&和||结合各个条件。


20.6 文件目录属性判断

shell脚本还需要和文件打交道,那么文件和目录的属性判断就至关重要的。

比如要判断是否为文件,且存在

#!/bin/bash
f="/tmp/aminglinux"
if [ -f $f ]
then
    echo $f exist
else
    touch $f
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -f /tmp/aminglinux ]
+ touch /tmp/aminglinux
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -f /tmp/aminglinux ]
+ echo /tmp/aminglinux exist
/tmp/aminglinux exist

判断是否为目录,且存在

#!/bin/bash
f="/tmp/aminglinux"
if [ -d $f ]
then
    echo $f exist
else
    touch $f
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -d /tmp/aminglinux ]
+ touch /tmp/aminglinux

判断是否存在

#!/bin/bash
f="/tmp/aminglinux"
if [ -e $f ]
then
    echo $f exist
else
    touch $f
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -e /tmp/aminglinux ]
+ echo /tmp/aminglinux exist
/tmp/aminglinux exist

判断文件是否可读

#!/bin/bash
f="/tmp/aminglinux"
if [ -r $f ]
then
    echo $f readable
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -r /tmp/aminglinux ]
+ echo /tmp/aminglinux readable
/tmp/aminglinux readable

判断文件是否可写

#!/bin/bash
f="/tmp/aminglinux"
if [ -w $f ]
then
    echo $f writeable
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -w /tmp/aminglinux ]
+ echo /tmp/aminglinux writeable
/tmp/aminglinux writeable

判断文件是否可执行

#!/bin/bash
f="/tmp/aminglinux"
if [ -x $f ]
then
    echo $f excutable
else
    echo $f not excutable
fi
[email protected]:~/shell_script# sh -x file1.sh
+ f=/tmp/aminglinux
+ [ -x /tmp/aminglinux ]
+ echo /tmp/aminglinux not excutable
/tmp/aminglinux not excutable

这些权限都是执行脚本用户的权限。

很多时候,写的脚本太长,有简单等价写法。下面两段就是等价的。

#!/bin/bash
f="/tmp/aminglinux"
[ -f $f ] && rm -f $f
#!/bin/bash
f="/tmp/aminglinux"
if [ -f $f ] 
then
    rm -f $f
fi

同理读者可以尝试写一下文件不存在创建文件的脚本

[ -f $f ] || touch $f
if [ ! -f $f ]
then
    touch $f
fi

 

20.7 if特殊用法

判断变量的值是否为空

#!/bin/bash
n=`wc -l /tmp/lala`
if [ $n -gt 100]
then 
    echo alert!
fi

有时候我们判断某个文件的行数,大于100报警,这样写肯定是对的,但是如果有人误操作把你的文件删除了呢,这个就会报错。

[email protected]:~/shell_script# sh -x special_if.sh 
+ wc -l /tmp/lala
wc: /tmp/lala: No such file or directory
+ n=
+ [ -gt 100]
special_if.sh: 3: [: missing ]

而且是语法错误。

所以脚本为了防止这样的bug,更加严谨,应该这么写。

#!/bin/bash
n=`wc -l /tmp/lala`
if [ ! -n "$n" ]
then
    exit
elif [ $n -gt 100]
then
    echo alert!
fi
[email protected]:~/shell_script# sh -x special_if.sh 
+ wc -l /tmp/lala
wc: /tmp/lala: No such file or directory
+ n=
+ [ ! -n  ]
+ exit

[ ! -n "$n" ] 和 [ -z "$n" ]是等价的,这里注意,双引号是必要的,为了统一,建议所有变量都加双引号。

如果想更好一点,就先判断文件是否存在,也要判断n是否为空,总之,怎么严格怎么来。

当然这个也可以判断文件是否为空,判断文件的时候不必加双引号。

[email protected]:~/shell_script# ls
file1.sh  if1.sh  special_if.sh  test.sh
[email protected]:~/shell_script# if [ -n "file1.sh" ]; then echo ok; fi
ok
[email protected]:~/shell_script# if [ -n file1.sh ]; then echo ok; fi
ok

if判断也可以用grep做条件

[email protected]:~/shell_script# grep -w 'lhy' /etc/passwd
lhy:x:1000:1000:lhy,,,:/home/lhy:/bin/bash
[email protected]:~/shell_script# if grep -w 'lhy' /etc/passwd; then echo "lhy exists"; fi
lhy:x:1000:1000:lhy,,,:/home/lhy:/bin/bash
lhy exists
[email protected]:~/shell_script# if grep -wq 'lhy' /etc/passwd; then echo "lhy exists"; fi
lhy exists

防止grep输出,可以使用quiet模式

[email protected]:~/shell_script# if ! grep -wq 'user1' /etc/passwd; then echo "user1 not exists"; fi
user1 not exists

最后,[]中不能使用<,>,==,!=,>=,<=这样的符号。


20.8/9 case判断

C语言中的case判断和在shell中的语法非常像。

格式为

case "$var" in
    value1)
        statement
        ;;
    value2)
        statement
        ;;
    *)
        statement
        ;;
esac

value中不能包含元字符:*、?、[..](类,如[a-z]等)

value中可以包含或符号(|),表示多个匹配,如y|Y|yes|YES

*表示缺省

匹配的时候从上到下依次匹配,双分号表示break。

[email protected]:~/shell_script# cat case1.sh 
#!/bin/bash
read -p "Please input a number: " n
if [ -z "$n" ]  #判断n是否为空
then
    echo "Please input a number."
    exit 1
fi

n1=`echo $n|sed 's/[0-9]//g'`  #判断是否有非数字输入
if [ -n "$n1" ]
then
 echo "Please input a number."
 exit 1
fi

if [ $n -lt 60 ] && [ $n -ge 0 ]
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 "not ok"
        ;;
    2)
        echo "ok"
        ;;
    3)
        echo "ook"
        ;;
    4)
        echo "oook"
        ;;
    *)
        echo "The number range is 0-100."
        ;; 
esac
[email protected]:~/shell_script# sh -x case1.sh 
+ read -p Please input a number:  n
Please input a number: 99
+ [ -z 99 ]
+ echo 99
+ sed s/[0-9]//g
+ n1=
+ [ -n  ]
+ [ 99 -lt 60 ]
+ [ 99 -ge 60 ]
+ [ 99 -lt 80 ]
+ [ 99 -ge 80 ]
+ [ 99 -lt 90 ]
+ [ 99 -ge 90 ]
+ [ 99 -le 100 ]
+ tag=4
+ echo oook
oook

如果你写的各个条件有交叉的部分,一定要安排好顺序,因为一个匹配上之后就不会去匹配另外一个了。

下面测试下非双分号结尾。参考文章

#!/bin/bash

case "1" in
    1)
        echo '1'
        ;;&
    2)
        echo '2'
        ;;
    3)
        echo '3'
        ;;
    1)
        echo "1 again"
        ;;
    *)
        echo '*'
        ;;
esac
[email protected]:~/shell_script# bash -x case2.sh 
+ case "1" in
+ echo 1
1
+ echo '1 again'
1 again

这个结尾(;;&)叫做conditional follow up 。只要满足条件,不会退出,会继续匹配后面的能满足条件的选项。

#!/bin/bash

case "1" in
    1)
        echo '1'
        ;&
    2)
        echo '2'
        ;;
    3)
        echo '3'
        ;;
    1)
        echo "1 again"
        ;;
    *)
        echo '*'
        ;;
esac
[email protected]:~/shell_script# bash -x case2.sh 
+ case "1" in
+ echo 1
1
+ echo 2
2

这个结尾(;&)叫做unconditional follow up 。只要满足条件,不会退出,会继续匹配下一个选项。

 

转载于:https://my.oschina.net/u/3866688/blog/2052042