20.5 shell脚本中的逻辑判断

不带else

格式1:if 条件 ; then 语句; fi(这种格式常用)

解释:

如果满足条件,然后怎样,最后怎样

比较参数解释:eq EQ  EQUAL             等于

nq NQ  NOT EQUAL         不等于

gt GT  GREATER THAN        大于

lt LT  LESS THAN         小于

ge GE  GREATER THAN OR EQUAL   大于等于

le LE  LESS THAN OR EQUAL    小于等于

实例:

1 命令行形式表示[root@AliKvn ~]# a=5

[root@AliKvn ~]# if [ $a -gt 3 ]

> then

> echo ok

> fi

ok

[root@AliKvn ~]# if [ $a -gt 3 ]; then echo ok; fi

解释:

-gt 3 表示大于3

整条参数的意思就是,如果a大于3,显示ok.

上面2条参数都是同样效果,分开写就用上面的格式,一条命令的格式就参考下面的。

2 脚本形式表示

编写脚本[root@AliKvn shell]# vim if1.sh

#!/bin/bash

a=5

if [ $a -gt 3 ]

then

echo ok

fi

执行[root@AliKvn shell]# sh if1.sh

ok

带有else,表示否则。

格式2:if 条件; then 语句; else 语句; fi

解释:如果满足条件,然后怎样;如果不满足条件,然后怎样。

实例:

1 编写脚本

a=1,大于3就ok,否则,no.[root@AliKvn shell]# vim if2.sh

#!/bin/bash

a=1

if [ $a -gt 3 ]

then

echo ok

else

echo no

fi

2 执行过程

[root@AliKvn shell]# sh -x if2.sh

+ a=1a=1

+ '[' 1 -gt 3 ']'1与3比较,不满足>3条件,

+ echo no但是满足脚本中的else

no所以最后输出结果是no

带有elif,附件条件,同个脚本可以写多个elif

格式3:if …; then … ;elif …; then …; else …; fi

解释:

实例:

1 编写脚本[root@AliKvn shell]# vim if3.sh

#!/bin/bash

a=3

if [ $a -gt 4 ]

then

echo ">1"

elif [$a -gt 6]

then

echo "<6 && >1"

else

echo no

fi

参数解释:

elif [$a -gt 6]而且a>6,

then

echo "<6 && >1"则输出结果:<6 && >1

2 执行过程[root@AliKvn shell]# sh -x if3.sh

+ a=3

+ '[' 3 -gt 4 ']'

+ '[' 3 -gt 6 ']'

+ echo no

no

逻辑判断表达式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等

大于小于等于等说明:-gt (>); -lt(=); -le(<=);-eq(==); -ne(!=) 注意到处都是空格

大于小于等于也可以用这种方法表示,[root@AliKvn shell]# a=3

[root@AliKvn shell]# if ((a>1)); then echo ok; fi

ok

可以使用 && || 结合多个条件(&&并且,||或者)if [ $a -gt 5 ] && [ $a -lt 10 ]; then

if [ $b -gt 5 ] || [ $b -lt 3 ]; then

20.6 文件目录属性判断

[ -f file ]判断是否是普通文件,且存在

实验

1 编写脚本[root@AliKvn shell]# !vim

vim file-f.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -f $f ]

then

echo $f exist.

else

touch $f

fi

解释:

f="/tmp/shell-f.test" 变量f=/tmp/shell-f.test这个文件,

if [ -f $f ]如果它是个文件,

then则

echo $f exist.输出$f变量exist

else否则

touch $f创建$f文件

fi

2 执行脚本查看进度[root@AliKvn shell]# sh -x file-f.sh

+ f=/tmp/shell-f.test

+ '[' -f /tmp/shell-f.test ']'

+ echo /tmp/shell-f.test exist.

/tmp/shell-f.test exist.

[ -d file ] 判断是否是目录,且存在

1 编写脚本[root@AliKvn shell]# vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -d $f ]

then

echo $f exist.

else

touch $f

fi

解释:

if [ -d $f ] -d判断变量$f是否目录

touch $f 目录和文件都可以进行touch的。touch$f,如果存在,也不影响操作,只影响time

2 执行脚本查看进度

[root@AliKvn shell]# sh -x file-d.sh

+ f=/tmp/shell-f.test

+ '[' -d /tmp/shell-f.test ']'

+ touch /tmp/shell-f.test

[ -e file ] 判断文件或目录是否存在,仅仅判断是否存

1 编写脚本,[root@AliKvn shell]# !vim

vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -e $f ]

then

echo $f exist.

else

touch $f

fi

2 执行脚本查看进度[root@AliKvn shell]# sh -x !$

sh -x file-d.sh

+ f=/tmp/shell-f.test

+ '[' -e /tmp/shell-f.test ']'

+ echo /tmp/shell-f.test exist.

/tmp/shell-f.test exist.

[ -r file ] 判断文件是否可读

1 编写脚本[root@AliKvn shell]# !vim

vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -r $f ]

then

echo $f readable

else

echo $f unreadable

fi

2 执行脚本[root@AliKvn shell]# sh  file-d.sh

/tmp/shell-f.test readable

[ -w file ] 判断文件是否可写

1 编写脚本

[root@AliKvn shell]# !vim

vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -r $f ]

then

echo $f writeable

else

echo $f unwriteable

fi

2 执行脚本[root@AliKvn shell]# sh  file-d.sh

/tmp/shell-f.test writeable

[ -e file ] 判断文件或目录是否存在

注意,执行判断脚本的可读可写可执行状态,只针对当前用户

#vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -r $f ]

then

echo $f writeable

else

echo $f unwriteable

fi

[root@AliKvn shell]# !vim

vim file-d.sh

#!/bin/bash

f="/tmp/shell-f.test"

if [ -f $f ]

then

rm -f $f

fi

以上脚本,倒数4条的内容,等同于这条参数[ -f $f ] && rm -f $f

&&表示前面的执行有效,后面才接着执行。

[ -f $f ] || touch $f

||表示或者,前者命令是否定答案,才执行后者命令。

以上都是用了如果存在的条件,

要表示如果文件不存在,应该是[! -f $f] !表示非,取反,否定意义。

总结:

if 判断文件、目录属性

[ -f file ]判断是否是普通文件,且存在

[ -d file ] 判断是否是目录,且存在

[ -e file ] 判断文件或目录是否存在

[ -r file ] 判断文件是否可读

[ -w file ] 判断文件是否可写

[ -x file ] 判断文件是否可执行

20.7 if特殊用法

if判断的一些特殊用法if [ -z  "$a" ]  这个表示当变量a的值为空时会怎么样。它与if [ -n "$a" ]是相对的,相反的。if [ -n "$a" ]=if [ ! -z "$a" ],他们是相同的。

if [-z  "$a" ] 这个表示当变量a的值为空时会怎么样。

if [ -n "$a" ] 这个表示当变量a的值不为空时,会怎样。不为空,条件成立。

! -z = -n

! -n = -z 他们的关系是相对的

使用-z和-n判断时,变量要用双引号括起来,文件和目录就不需要。

1 编写脚本,[root@AliKvn shell]# vim shell20-7.sh

#!/bin/bash

n=`wc -l /tmp/lalal`        n的值为统计文件的行数

if [ -z "$n" ]            如果n的值为空(或者文件是不存在)

then                                        则

echo error                        输出error

exit然后退出

elif [ $n -gt 1000 ]        如果输出结果大于1000

then则

echo ljfiwo        输出ljfiwo

fi

2 执行脚本并输出,略乱[root@AliKvn shell]# sh -x shell20-7.sh

++ wc -l /tmp/lalal

wc: /tmp/lalal: No such file or directory

+ n=

+ '[' -z '' ']'

+ echo error

error

+ exit

3 这个脚本还可以更完美

[root@AliKvn shell]# !vim

vim file-f.sh

#!/bin/bash

if [ ! -f /tmp/lalal ]                    判断/tmp/lalal是否非文件并判断是否非存在,

then                                条件成立则

echo "/tmp/lalal not exist."               输出结果

exit                        退出操作

fi

f="/tmp/shell-f.test"

if [ -f $f ]

then

echo $f exist.

else

touch $f

fi

4 执行脚本[root@AliKvn shell]# !vim

vim file-f.sh

[root@AliKvn shell]# sh -x !$

sh -x file-f.sh

+ '[' '!' -f /tmp/lalal ']'

+ echo '/tmp/lalal not exist.'

/tmp/lalal not exist.

+ exit

[root@AliKvn shell]# sh  file-f.sh

/tmp/lalal not exist.

if [ -n "$a" ] 表示当变量a的值不为空。可以判断文件,如果是字符串需要用双引号引起,否则不用双引号。

1 判断文件用法(不用双引号标注)

判断01.sh是否存在

[root@AliKvn shell]# ls

01.sh  file-d.sh  file-f.sh  if1.sh  if2.sh  if3.sh  shell20-7.sh

如果01.sh存在,那么输出yes

[root@AliKvn shell]# if [ -n 01.sh ]; then echo yes; fi

yes

2 判断变量用法(需要双引号标注)[root@AliKvn ~]# echo $b

[root@AliKvn ~]# if [ -n "$b" ]; then echo $b; else echo "b is not here"; fi

b is not here

命令的执行结果作为判断条件

1 判断系统中是否有mysql用户存在

解决思路:mysql——》/etc/passwd——》grep ——》再执行条件判断

操作:[root@AliKvn ~]# if grep -wq 'mysql' /etc/passwd; then echo "exist"; fi

exist

如果mysql1用户不存在,判断条件[root@AliKvn ~]# if ! grep -wq 'mysql1' /etc/passwd; then echo "don't exist"; fi

don't exist

如果mysql1用户不存在,判断条件[root@AliKvn ~]# if grep -wq 'mysql1' /etc/passwd; then echo "exist";else echo " don't exist "; fi

don't exist

以上两种方法的性质是一样的

同理

if [ ! -e file ]; then 表示文件不存在时会怎么样

if (($a<1)); then …等同于 if [ $a -lt 1 ]; then...

[ ] 中不能使用,==,!=,>=,<=这样的符号(=是赋值,==是等于)

20.8 case判断

shell中的case判断

在shell脚本中,除了用if来判断逻辑外,还有一种常用的方式,case.

case脚本常用于偏写系统服务的启动脚本。例如/etc/init.d/network中就用到了case

case脚本格式:

case 变量名 in

value1)            值为value1的时候

command            执行什么

;;                ;;表示一个判断结束,进入到下一个判断。

value2)            值为value2的时候

command            执行什么

;;

*)                除此之外的值

command              又执行什么

;;

esac                case的倒写,表示到此结束case脚本

在case程序中,可以在条件中使用|,表示或的意思, 比如

2|3)

command

;;

脚本案例

目的:让用户输入数值,然后用脚本判断数值的范围。

例如这个数字一个考试分数值,范围是0-100,然后再在0-100里面定义分数的级别:不合格,合格,优秀。

1 创建并编辑脚本[root@AliKvn shell]# cd /root/shell/

[root@AliKvn shell]# vim sh-case-test.sh

#!/bin/bash

read -p "Please input a number: " n

if [ -z "$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 "no pass"

;;

2)

echo "pass"

;;

3)

echo "good"

;;

4)

echo "very good"

;;

*)

echo "The number range is 0-100."

;;

esac

参数解释:(解释比较长)

#!/bin/bash

read -p "Please input a number: "  n

让用户输入字符串,其实这算与用户交互动作。

例如,read -p "xxx" n

显示的结果就是xxx:

那么read -p "Please input a number: " n

输出是Please input a number:

[root@AliKvn ~]# read -p "Please input a number: " n

Please input a number: 100

[root@AliKvn ~]# echo $n

100

if [ -z "$n" ]

如果n值为空,即用户没有输入n值

then

echo "Please input a number."

输出告知Please input a number.

exit 1

退出,并返回1个数值,这里的用法跟echo $?的输出一样

fi

n1=`echo $n|sed 's/[0-9]//g'`

判断变量n1输入的值是否纯数字,是纯数字的话,sed功能会将其解析置空(这里的置空仅仅用于命令条件作用,并不是把n值置空),置空的话下面的条件不成立(if,if为一对)

if [ -n "$n1" ]

当n1数值不为空时(注意,这里不是n值是n1,两者性质不同),会被当作输出不合法

then

echo "Please input a number."

继续输出Please input a number.

exit 1

如果n1不为空的话,退出这条件,然后继续判断其他条件

fi

那就是说,当用户输入的字符串(n值)为纯数字的话,条件成立(n1置空)。否则,用户输入的不是纯数字的话,条件不成立,被脚本认为是不合法输入,会继续输出Please input a number.

if [ $n -lt 60 ] && [ $n -ge 0 ]        条件能到这里,表示n是一个纯数字。当0

then                        则

tag=1                    转到标记1

elif [ $n -ge 60 ] && [ $n -lt 80 ]        当60

then则

tag=2转到标记2

elif [ $n -ge 80 ]  && [ $n -lt 90 ]        当80

then                        然后

tag=3                    转到标记3

elif [ $n -ge 90 ] && [ $n -le 100 ]        当90

then                        然后

tag=4                    转到标记4

else                         否则

tag=0                    转到标记0

fi

case $tag in

1)                    标记1(tag=1)

echo "no pass"                  输出no pass

;;

2)                      标记2

echo "pass"            输出pass

;;

3)                    标记3

echo "good"            输出good

;;

4)                    标记4

echo "very good"           very good

;;

*)                        以上4个标记都不符合的条件,这时候数值是等于0,又可能是大于100

echo "The number range is 0-100."    输出The number range is 0-100.提示用户输入正确的数值

;;

esac                        结束脚本

3 测试脚本[root@AliKvn shell]# sh sh-case-test.sh

Please input a number: 111

The number range is 0-100.

超过定义的范围100以外的数值,所以条件不成立,然后输出了不成立的信息,此处证明脚本的否定输出是ok的。

3.1 查看执行过程[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: 111

+ '[' -z 111 ']'

++ sed 's/[0-9]//g'

++ echo 111

+ n1=

+ '[' -n '' ']'

+ '[' 111 -lt 60 ']'

+ '[' 111 -ge 60 ']'

+ '[' 111 -lt 80 ']'

+ '[' 111 -ge 80 ']'

+ '[' 111 -lt 90 ']'

+ '[' 111 -ge 90 ']'

+ '[' 111 -le 100 ']'

+ tag=0

+ case $tag in

+ echo 'The number range is 0-100.'

The number range is 0-100.

3.2 输入不合法的数值数值,例如中英文。[root@AliKvn shell]# sh  sh-case-test.sh

Please input a number: ah1

Please input a number.

执行过程[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: ah1

+ '[' -z ah1 ']'

++ sed 's/[0-9]//g'

++ echo ah1

+ n1=ah

+ '[' -n ah ']'

+ echo 'Please input a number.'

Please input a number.

+ exit 1

3.3 正确的范围输出结果(0-100)[root@AliKvn shell]# sh  sh-case-test.sh

Please input a number: 60

pass

[root@AliKvn shell]# sh  sh-case-test.sh

Please input a number: 88

good

[root@AliKvn shell]# sh  sh-case-test.sh

Please input a number: 98

very good

[root@AliKvn shell]# sh  sh-case-test.sh

Please input a number: 100

very good

完全符合刚刚定义的参数配置,成功。下面再看看执行脚本过程。

3.4 执行脚本过程[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: 60

+ '[' -z 60 ']'

++ sed 's/[0-9]//g'

++ echo 60

+ n1=

+ '[' -n '' ']'

+ '[' 60 -lt 60 ']'

+ '[' 60 -ge 60 ']'

+ '[' 60 -lt 80 ']'

+ tag=2

+ case $tag in

+ echo pass

pass

[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: 88

+ '[' -z 88 ']'

++ sed 's/[0-9]//g'

++ echo 88

+ n1=

+ '[' -n '' ']'

+ '[' 88 -lt 60 ']'

+ '[' 88 -ge 60 ']'

+ '[' 88 -lt 80 ']'

+ '[' 88 -ge 80 ']'

+ '[' 88 -lt 90 ']'

+ tag=3

+ case $tag in

+ echo good

good

[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: 98

+ '[' -z 98 ']'

++ sed 's/[0-9]//g'

++ echo 98

+ n1=

+ '[' -n '' ']'

+ '[' 98 -lt 60 ']'

+ '[' 98 -ge 60 ']'

+ '[' 98 -lt 80 ']'

+ '[' 98 -ge 80 ']'

+ '[' 98 -lt 90 ']'

+ '[' 98 -ge 90 ']'

+ '[' 98 -le 100 ']'

+ tag=4

+ case $tag in

+ echo 'very good'

very good

[root@AliKvn shell]# sh -x sh-case-test.sh

+ read -p 'Please input a number: ' n

Please input a number: 100

+ '[' -z 100 ']'

++ sed 's/[0-9]//g'

++ echo 100

+ n1=

+ '[' -n '' ']'

+ '[' 100 -lt 60 ']'

+ '[' 100 -ge 60 ']'

+ '[' 100 -lt 80 ']'

+ '[' 100 -ge 80 ']'

+ '[' 100 -lt 90 ']'

+ '[' 100 -ge 90 ']'

+ '[' 100 -le 100 ']'

+ tag=4

+ case $tag in

+ echo 'very good'

very good

4 done.