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(<); -ge(>=); -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
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 good4 done.