在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
#不使用分号将会是这样的
[root@123 ~]# for i in `seq 1 5`
> do
> echo $i
> done
格式1:if条件;then 语句;if
在命令行操作
a=6
if [ $a -gt 3 ]; then echo ok; fi
说明:方括号两边需要有空格,-gt 是大于, $a大于3,那么这肯定OK的.
在脚本里写,就整理一下格式即可,然后再执行
#! /bin/bash
a=6
if [ $a -gt 3 ]
then
echo ok
fi
sh 04.sh
格式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
#如果$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
说明:如果$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
说明:如果$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
说明:if [ -f $f ] 判断/tmp/linux 是否存在,明显是不存在的,所有就touch 了这个文件
# 重新执行一次,判断文件是否存在,若存就输出结果
sh -x file1.sh
说明:前面不存在就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
说明:if [ -d $d ] 判断/tmp/linux 是否存在,明显是不存在的,所有就mkdir 了这个文件
#重新执行一次,判断目录是否存在,若存在就输出
sh -x file2.sh
说明:前面不存在就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
说明:-e 不管是文件或目录,是判断是否存在,不存在的话就touch
[ -r file ] 判断文件是否可读
vim file2.sh
#! /bin/bash
f="/tmp/Anna"
if [ -r $f ]
then
echo $f readable
fi
#执行
sh file2.sh
[ -w file ] 判断文件是否可写
vim file2.sh
#! /bin/bash
f="/tmp/Anna"
if [ -w $f ]
then
echo $f writeable
fi
#执行
sh file2.sh
说明:可写是针对当前root用户,若切换到user用户,那么就只有可读的权限,没有可读权限
[ -x file ] 判断文件是否可执行
vim file2.sh
#! /bin/bash
f="/tmp/Anna"
if [ -x $f ]
then
echo $f exeable
fi
#执行
sh file2.sh
说明:可写是针对当前root用户,若切换到user用户,那么就只有可读的权限,没有可执行权限
判断一个目录是否存在,如果存在删除掉
vim file2.sh
#! /bin/bash
d="/tmp/Anna"
if [ -d $d ]
then
rmdir $d
fi
#执行
sh -x file2.sh
#判断一个目录是否存在,如果存在就输出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
#! /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,如有则删除。
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
还可修改为如下,先添加判断/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
)
if [ -n 01.sh ]; then echo ok; else echo "01.sh is null"; fi
说明: 判断01.sh 是否为空,不为空 ,输出ok
if [ -n "$b" ]; then echo $b; else echo "b is null"; fi
说明:判断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
说明:查看是否有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
说明: 先判断/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
#执行,输入数字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'
优秀
# 执行,输入非数字,就会提示请输入数字
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
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
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
若想这种脚本不意外的终止,可以打开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
sh berak.sh
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
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
扩展
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html