目录
一、shell脚本中的逻辑判断
二、文件目录属性判断
三、if特殊用法
四、case判断
五、for循环
六、while循环
七、break跳出循环
八、continue结束本次循环
九、exit退出整个脚本
一、shell脚本中的逻辑判断
- 格式1:if 条件 ; then 语句; fi
##条件需要使用方括号 [] 或者 双括号(()) 括起来
[root@minglinux-01 /usr/local/sbin] a=5
[root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]
> then
> echo ok
> fi
ok
[root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]; then echo ok; fi
ok
[root@minglinux-01 /usr/local/sbin] if (($a>3)); then echo ok; fi
ok
[root@minglinux-01 /usr/local/sbin] vim if1.sh
1 #!/bin/bash
2 a=5
3 if [ $a -gt 3 ];then
4 echo ok
5 fi
[root@minglinux-01 /usr/local/sbin] sh if1.sh
ok
- 格式2:if 条件; then 语句; else 语句; fi
[root@minglinux-01 /usr/local/sbin] vim if2.sh
1 #!/bin/bash
2 a=2
3 if [ $a -gt 3 ];then
4 echo ok
5 else
6 echo no
7 fi
[root@minglinux-01 /usr/local/sbin] sh if2.sh
no
- 格式3:if …; then … ;elif …; then …; else …; fi
[root@minglinux-01 /usr/local/sbin] vim if3.sh
1 #!/bin/bash
2 a=3
3 if [ $a -lt 3 ];then
4 echo "a<3"
5 elif [ $a -ge 3 ] && [ $a -le 6 ];then
6 echo "a>=3 && a<=6"
7 else
8 echo "a<3"
9 fi
[root@minglinux-01 /usr/local/sbin] sh if3.sh
a>=3 && a<=6
[root@minglinux-01 /usr/local/sbin] sh -x if3.sh
+ a=3
+ '[' 3 -lt 3 ']'
+ '[' 3 -ge 3 ']'
+ '[' 3 -le 6 ']'
+ echo 'a>=3 && a<=6'
a>=3 && a<=6
&& 表示当前一条命令成功才执行后面的命令
|| 表示当前一条命令不成功时执行后面的命令
-lt (小于)、-gt(大于)、-le(小于或等于)、-ge(大于
或等于)、-eq(等于)、-ne(不等于)
二、文件目录属性判断
shell脚本中if还经常用于判断文档的属性,if常用的选项有以下几个:
[ -f file ]判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或目录是否存在,存在为真
[ -b file ] 判断文件是块特殊文件为真
[ -c file ] 判断文件是字符特殊文件为真
[ -s file ] 判断文件大小非0时为真
[ -r file ] 判断文件是否可读,可读为真
[ -w file ] 判断文件是否可写,可写为真
[ -x file ] 判断文件是否可执行,可执行为真
- 示例代码如下
[root@minglinux-01 ~] if [ -f /root/ ]; then echo ok; fi #/root/不是文件,不显示ok
[root@minglinux-01 ~] if [ -d /root/ ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -e /root/ ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -e /root/a.txt ]; then echo ok; fi
[root@minglinux-01 ~] if [ -e /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -r /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -w /root/1.txt ]; then echo ok; fi
ok
[root@minglinux-01 ~] if [ -x /root/1.txt ]; then echo ok; fi
[root@minglinux-01 ~] ls -l 1.txt
-rw-r--r--. 1 root root 2 11月 1 23:47 1.txt
三、if特殊用法
- if [ -z "$a" ] 判断变量a的值是否为空,空为真
[root@minglinux-01 ~] wc -l RNG.sh
51 RNG.sh
[root@minglinux-01 ~] a=`wc -l RNG.sh`
[root@minglinux-01 ~] if [ -z "$a" ]; then echo error; else echo $a; fi
51 RNG.sh
[root@minglinux-01 ~] if [ ! -z "$a" ]; then echo error; else echo $a; fi
error
- if [ -n "$a" ] 判断变量a的值是否为空,非空为真
[root@minglinux-01 ~] if [ -n "$a" ]; then echo error; else echo $a; fi
error
[root@minglinux-01 ~] if [ ! -n "$a" ]; then echo error; else echo $a; fi
51 RNG.sh
-n和-z只能作用于变量,无法作用于文件
- if grep -q '123' 1.txt; then 判断文件中是否包含'123'字符串,包含则为真
[root@minglinux-01 ~] cat 2.txt
c b a
3 2 1
6 5 4
[root@minglinux-01 ~] if grep -q 'a' 2.txt; then echo "Yes"; else echo "No"; fi
Yes
[root@minglinux-01 ~] if grep -q 'd' 2.txt; then echo "Yes"; else echo "No"; fi
No
- if [ ! -e file ]; then 判断文件是否存在,不存在为真
[root@minglinux-01 ~] if [ ! -e ./qwer ]; then echo "不存在"; fi
不存在
四、case判断
- 格式:
case 变量 in
value1)
command
;;
value2)
command
;;
value3)
command
;;
*)
command
;;
esac
在case程序中,可以在条件中使用|,表示或的意思,如:
2|3)
command
;;
- 脚本示例
[root@minglinux-01 /usr/local/sbin] vim case.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 "not ok"
;;
2)
echo "ok"
;;
3)
echo "ook"
;;
4)
echo "oook"
;;
*)
echo "The number range is 0-100."
;;
esac
[root@minglinux-01 /usr/local/sbin] sh case.sh
Please input a number: 100
oook
[root@minglinux-01 /usr/local/sbin] sh case.sh
Please input a number: 1
not ok
[root@minglinux-01 /usr/local/sbin] sh case.sh
Please input a number:
Please input a number.
[root@minglinux-01 /usr/local/sbin] sh case.sh
Please input a number: 7897
The number range is 0-100.
[root@minglinux-01 /usr/local/sbin] echo $?
0
五、for循环
- 语法:for 变量名 in 条件; do …; done
计算1到10数字之和
[root@minglinux-01 /usr/local/sbin] vim for1.sh
1 #!/bin/bash
2 sum=0
3 for i in `seq 1 10`
4 do
5 sum=$[$sum+$i]
6 done
7 echo $sum
[root@minglinux-01 /usr/local/sbin] sh -x for1.sh
+ sum=0
++ seq 1 10
+ for i in '`seq 1 10`'
+ sum=1
+ for i in '`seq 1 10`'
+ sum=3
+ for i in '`seq 1 10`'
+ sum=6
+ for i in '`seq 1 10`'
+ sum=10
+ for i in '`seq 1 10`'
+ sum=15
+ for i in '`seq 1 10`'
+ sum=21
+ for i in '`seq 1 10`'
+ sum=28
+ for i in '`seq 1 10`'
+ sum=36
+ for i in '`seq 1 10`'
+ sum=45
+ for i in '`seq 1 10`'
+ sum=55
+ echo 55
55
[root@minglinux-01 /usr/local/sbin] vim for1.sh
1 #!/bin/bash
2 sum=0
3 for i in `seq 1 10`
4 do
5 echo "$sum + $i"
6 sum=$[$sum+$i]
7 echo $sum
8 done
9 echo $sum
[root@minglinux-01 /usr/local/sbin] sh for1.sh
0 + 1
1
1 + 2
3
3 + 3
6
6 + 4
10
10 + 5
15
15 + 6
21
21 + 7
28
28 + 8
36
36 + 9
45
45 + 10
55
55
文件列表循环
[root@minglinux-01 /usr/local/sbin] vim for2.sh
1 #!/bin/bash
2 cd /root/
3 for i in `ls /root/`
4 do
5 if [ -d $i ]
6 then
7 ls -d $i
8 fi
9 done
[root@minglinux-01 /usr/local/sbin] sh for2.sh
dir2
log
logs
rsync
temp
[root@minglinux-01 /usr/local/sbin] sh -x for2.sh
+ cd /root/
++ ls /root/
+ for i in '`ls /root/`'
+ '[' -d 123.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 123.tzr ']'
+ for i in '`ls /root/`'
+ '[' -d 1.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 2.txt ']'
+ for i in '`ls /root/`'
+ '[' -d 3.txt ']'
+ for i in '`ls /root/`'
+ '[' -d b.txt ']'
+ for i in '`ls /root/`'
+ '[' -d cron.log ']'
+ for i in '`ls /root/`'
+ '[' -d dir2 ']'
+ ls -d dir2
dir2
+ for i in '`ls /root/`'
+ '[' -d log ']'
+ ls -d log
log
+ for i in '`ls /root/`'
+ '[' -d logs ']'
+ ls -d logs
logs
+ for i in '`ls /root/`'
+ '[' -d my.cnf ']'
+ for i in '`ls /root/`'
+ '[' -d qq.txt ']'
+ for i in '`ls /root/`'
+ '[' -d RNG.sh ']'
+ for i in '`ls /root/`'
+ '[' -d rsync ']'
+ ls -d rsync
rsync
+ for i in '`ls /root/`'
+ '[' -d sim.pid ']'
+ for i in '`ls /root/`'
+ '[' -d temp ']'
+ ls -d temp
temp
+ for i in '`ls /root/`'
+ '[' -d test.sh ']'
+ for i in '`ls /root/`'
+ '[' -d zabbix-release-3.2-1.el7.noarch.rpm ']'
#for循环时,会以空格或回车作为分隔符
[root@minglinux-01 /usr/local/sbin] mkdir test
[root@minglinux-01 /usr/local/sbin] cd test
[root@minglinux-01 /usr/local/sbin/test] touch 1 2 a\ b
[root@minglinux-01 /usr/local/sbin/test] ls -l
总用量 0
-rw-r--r-- 1 root root 0 1月 4 20:22 1
-rw-r--r-- 1 root root 0 1月 4 20:22 2
-rw-r--r-- 1 root root 0 1月 4 20:22 a b
[root@minglinux-01 /usr/local/sbin/test] for i in `ls ./`; do echo $i; done
1
2
a
b
#a空格b是一个文件,for循环却将a b拆成a、b两个对象
六、while循环
- 语法: while 条件; do … ; done
案例一
需求:每隔半分钟检查一次系统的负载,当系统负载大于10时,发一封邮件给管理员
[root@minglinux-01 ~] w
17:31:33 up 1 day, 21:05, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/1 192.168.162.1 16:14 1:09m 0.40s 0.15s vim while1.s
root pts/2 192.168.162.1 16:22 5.00s 0.15s 0.01s w
[root@minglinux-01 ~] uptime
17:31:47 up 1 day, 21:05, 2 users, load average: 0.00, 0.01, 0.05
[root@minglinux-01 ~] w |head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1
0
[root@minglinux-01 ~] uptime|awk -F 'load average: ' '{print $2}'|cut -d . -f1
0
##编写监控脚本如下
[root@minglinux-01 /usr/local/sbin] vim while1.sh
1 #!/bin/bash
2 while true ##使用true和:(冒号)都表示真,进入无限循环
3 do
4 load=`w|head -1|awk -F 'load average: ' '{print $2} `
1 #!/bin/bash
2 while true
2 while true
3 do
4 load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1`
5 if [$load -gt 10]
6 then
7 /usr/local/sbin/mail.py 331601950@qq.com "load high" "$load"
8 fi
9 sleep 30
10 done
##执行脚本
[root@minglinux-01 /usr/local/sbin] sh -x while1.sh
+ true
++ w ##第一次
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ cut -d . -f1
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30
+ true
++ w ##第二次
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ cut -d . -f1
+ load=0
+ '[' 0 -gt 10 ']'
+ sleep 30
···
···
若不想让脚本出现意外终止,可以在screen中运行脚本
案例二
需求:交互方式输入数字,根据输入数字判断后打印输出
[root@minglinux-01 /usr/local/sbin] cat while2.sh
#!/bin/bash
while :
do
read -p "请输入一个数字: " n
if [ -z "$n" ]
then
echo "你需要输入东西"
continue
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ ! -z $n1 ]
then
echo "你只能输入一个纯数字"
continue
fi
break
done
echo $n
[root@minglinux-01 /usr/local/sbin] sh while2.sh
请输入一个数字:
你需要输入东西
请输入一个数字: 12a
你只能输入一个纯数字
请输入一个数字: 123
123
七、break跳出循环
[root@minglinux-01 /usr/local/sbin] cat break.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 2 ] ##数字间比较时使用-eq/-lt/-gt等,字符时比较使用==
then
break
fi
echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh break.sh
1
1
2
ok
八、continue结束本次循环
##忽略continue之下的代码,直接进行下一次循环
[root@minglinux-01 /usr/local/sbin] cat continue.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 2 ]
then
continue
fi
echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh continue.sh
1
1
2
3
3
4
4
5
5
ok
九、exit退出整个脚本
[root@minglinux-01 /usr/local/sbin] cat exit.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 2 ]
then
exit
fi
echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh exit.sh
1
1
2
##通常exit执行后会返回一个状态码,该状态码可自定义,如下
[root@minglinux-01 /usr/local/sbin] cat exit.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 2 ]
then
exit 1
fi
echo $i
done
echo "ok"
[root@minglinux-01 /usr/local/sbin] sh exit.sh
1
1
2
[root@minglinux-01 /usr/local/sbin] echo $?
1
网友评论