9.14任务
20.5 shell脚本中的逻辑判断
逻辑判断格式大抵三种。
- if condition; then statement; fi
-
if condition; then statement; else statement; fi
-
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