测试概述
Shell脚本的智能化
使Shell脚本获得识别能力
为命令的执行提供最直接的识别依据
---文件或目录的读/写等状态
---数值的大小
---字符串是否匹配
---多条件组合
条件测试
一、语法格式
---test 表达式
---[ 表达式 ]
二、字符串比较
[ 操作符 字符串 ]
操作符
-z 字符串的值为空
-n 字符串的值不为空(相当于 ! -z)
[ 字符串1 操作符 字符串2 ]== 两个字符串相同
!= 两个字符串不相同
[root@pc2 ~]# test abc == abc
[root@pc2 ~]# echo $?
0
[root@pc2 ~]# test abc == xyz
[root@pc2 ~]# echo $?
1
[root@pc2 ~]# [ abc == abc ]
[root@pc2 ~]# echo $?
0
[root@pc2 ~]# [ abc == xyz ]
[root@pc2 ~]# echo $?
1
[root@pc2 ~]# [ abc != xyz ]
[root@pc2 ~]# echo $?
0
[root@pc2 ~]# [ abc != abc ]
[root@pc2 ~]# echo $?
1
[root@pc2 ~]# a=abc
[root@pc2 ~]# b=xyz
[root@pc2 ~]# [ $a == $b ]
[root@pc2 ~]# echo $?
1
[root@pc2 ~]# b=abc
[root@pc2 ~]# [ $a == $b ]
[root@pc2 ~]# echo $?
0
[root@pc2 ~]# [ $a == $c ]
-bash: [: abc: 需要一元表达式
[root@pc2 ~]# [ $a == "$c" ]
[root@pc2 ~]# echo $?
1
三、整数值比较
格式
---[ 整数值1 操作符 整数值2 ]操作符 含义
-eq 相等
-ne 不等
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
检查已登录的用户数,是否超过5个
# who | wc -l
# [ $(who | wc -l) -le 5 ] && echo "ok"
[root@pc2 opt]# x=20
[root@pc2 opt]# [ $x -eq 20 ] && echo yes || echo no
yes
[root@pc2 opt]# [ $x -ne 20 ] && echo yes || echo no
no
[root@pc2 opt]# [ $x -gt 20 ] && echo yes || echo no
no
[root@pc2 opt]# [ $x -ge 20 ] && echo yes || echo no
yes
[root@pc2 opt]# [ $x -lt 20 ] && echo yes || echo no
no
[root@pc2 opt]# [ $x -le 20 ] && echo yes || echo no
yes
[root@pc2 opt]#
四、文件状态
[ 操作符 文件或目录 ]
-e 判断文件是否存在,不关心文件类型
-f 判断文件是否存在,必须是普通文件
-d 判断文件是否存在,必须是目录
-r 判断当前用户对文件是否有读权限
-w 判断当前用户对文件是否有写权限
-x 判断当前用户对文件是否有 x 权限
组合多个条件
逻辑分隔操作
主要用法:
---命令1 操作符 命令2 ......
---[ 条件1 ] 操作符 [ 条件2 ] ......
操作符
---&& 与(前面命令执行成功,在执行后面命令;前面不成功不执行后面)
---|| 或(前面命令执行成功,后面命令不执行;前面命令执行不成功,后面命令执行)
#!/bin/bash
[ $USER != root ] && echo 需要root管理员执行 && exit
yum -y install vsftpd
#!/bin/bash
usernum=`cat /etc/passwd | wc -l`
[ $usernum -gt 48 ] && echo 警告!用户增加 | mail -s 安全 root
#!/bin/bash
[ $# -lt 2 ] && echo "格式错误,将退出.
USAGE:bash test2.sh 用户名 密码" && exit
useradd $1
echo $2 | passwd --stdin $1
if选择结构
一、单分支
语法格式及特点:
---当条件成立时执行命令序列
---否则,不执行任何操作
if 条件测试;then
任务指令1
......
......
fi
二、双分支
语法格式及特点:
---当条件成立时执行命令序列1
---否则,执行命令序列2
if 条件测试;then
任务指令1
......
else
任务指令1
......
fi
#!/bin/bash
ping -c 3 -i 0.2 -W 1 192.168.88.2 &> /dev/null
if [ $? -eq 0 ];then
echo ping耶
else
echo ping不不不
fi
#!/bin/bash
dir=/if_test/cdrom
if [ -d $dir ];then
echo ok
else
mkdir -p $dir
echo "$dir 创建"
fi
#!/bin/bash
if [ $USER == root ];then
echo 我是管理员
echo 略略略略略略
else
echo 鹅是一个小卡了迷
echo no
fi
三、多分支
语法格式及特点:
---相当于if语句嵌套
---针对多个条件分别执行不同的操作
if 条件测试;then
任务指令1
......
elif 条件测试;then
任务指令1
......
elif 条件测试;then
任务指令1
......
......
else
任务指令1
......
fi
#!/bin/bash
read -p "请输入你的分数:" n
if [ $n -ge 90 ] && [ $n -le 100 ];then
echo 优秀
elif [ $n -ge 80 ] && [ $n -le 89 ];then
echo 良好
elif [ $n -ge 60 ] && [ $n -le 79 ];then
echo 加油
elif [ $n -ge 0 ] && [ $n -le 59 ];then
echo 很遗憾!
else
echo "没这个分数 滚蛋!"
fi
if后不一定要放条件测试语句,它的目的是分对错,正确则执行,错误则不执行
case分支
case 变量 in
模式1)
命令
......;;
模式2)
命令
......;;
*)
命令
...... #最后模式命令后双引号可以不打
esac
[root@pc2 opt]# vim test14.sh
#!/bin/bash
case $1 in
abc)
echo 1;;
xyz)
echo 2;;
*)
echo 3
esac
[root@pc2 opt]# bash test14.sh abc
1
[root@pc2 opt]# bash test14.sh xyz
2
[root@pc2 opt]# bash test14.sh 12
3
[root@pc2 opt]# bash test14.sh ad
3
[root@pc2 opt]# bash test14.sh
3
[root@pc2 opt]# vim test14.sh
#!/bin/bash
case $1 in
t)
touch $2;;
m)
mkdir $2;;
r)
rm -rf $2;;
*)
echo 请输入t、m、r
esac
[root@pc2 opt]# bash test14.sh t wenjian
[root@pc2 opt]# bash test14.sh m mulu
[root@pc2 opt]# ls
mulu test10.sh test12.sh test14.sh test2.sh test4.sh test6.sh test8.sh test.sh
name.txt test11.sh test13.sh test1.sh test3.sh test5.sh test7.sh test9.sh wenjian
[root@pc2 opt]# bash test14.sh r mulu
[root@pc2 opt]# ls
name.txt test11.sh test13.sh test1.sh test3.sh test5.sh test7.sh test9.sh wenjian
test10.sh test12.sh test14.sh test2.sh test4.sh test6.sh test8.sh test.sh
[root@pc2 opt]# bash test14.sh r wenjian
[root@pc2 opt]# ls
name.txt test11.sh test13.sh test1.sh test3.sh test5.sh test7.sh test9.sh
test10.sh test12.sh test14.sh test2.sh test4.sh test6.sh test8.sh test.sh
[root@pc2 opt]# bash test14.sh
请输入t、m、r
#!/bin/bash
col() { #定义函数col
echo -e "\033[$1m$2\033[0m"
}
case $1 in
start|kai|s)
/usr/local/nginx/sbin/nginx;;
stop|guan)
/usr/local/nginx/sbin/nginx -s stop;;
researt|r)
ss -ntulp | grep -q nginx
if [ $? -eq 0 ];then
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx
else
/usr/local/nginx/sbin/nginx
fi;;
status)
ss -ntulp | grep -q nginx
if [ $? -eq 0 ];then
col 32 服务运行中 #调用函数col
else
col 31 请启动服务 #调用函数col
fi;;
*)
echo erro
esac
循环结构
一、for 循环
语法结构及特点:
遍历/列表式循环
---根据变量的不同取值,重复执行命令序列
for 变量名 in 值1 值2 值3
do
命令序列
......
done
#!/bin/bash
for i in a b c
do
echo xyz
echo "$i"
done
[root@pc2 opt]# cat name.txt
asda
afdfv
awerwr
vbz
af
xgvdafg
adgag
aerqt
[root@pc2 opt]# vim test8.sh
#!/bin/bash
for i in $(cat /opt/name.txt) #$()与``相等,将命令的输出作为变量值
do
useradd $i
done
#!/bin/bash
ok=0
fail=0
for i in {1..10} #{a..b} a到b
do
ping -c 3 -i 0.1 -W 1 192.168.88.$i &> /dev/null
if [ $? -eq 0 ];then
echo 192.168.88.$i通
#let ok++
let ok+=1
elif [ $? -ne 0 ];then
echo 192.168.88.$i不通
#let fail++
let fail+=1
fi
done
echo $ok 成功,$fail 失败
for((初值;条件;步长))
do
任务
done
[root@pc2 opt]# vim test10.sh
#!/bin/bash
for((a=1;a<=5;a++))
do
echo abc
echo "$a"
done
[root@pc2 opt]# bash test10.sh
abc
1
abc
2
abc
3
abc
4
abc
5
二、while循环
语法结构及特点:
条件式循环
---反复测试条件,只要成立就执行命令序列
while 条件测试
do
命令序列
done
#!/bin/bash
while :
do
echo abc
done
循环的中断与退出
一、exit(结束循环以及整个脚本)
[root@pc2 opt]# vim test12.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && exit
echo ok$i
done
echo over
[root@pc2 opt]# bash test12.sh
ok1
ok2
二、break(结束循环,继续循环之后任务)
[root@pc2 opt]# vim test12.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && break
echo ok$i
done
echo over
[root@pc2 opt]# bash test12.sh
ok1
ok2
over
三、continue(结束当前循环,进入下一次循环)
[root@pc2 opt]# vim test12.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && continue
echo ok$i
done
echo over
[root@pc2 opt]# bash test12.sh
ok1
ok2
ok4
ok5
over
#!/bin/bash
x=0
while :
do
read -p "请输入整数(0是结束看结果):" n
[ -z $n ] && continue
[ $n -eq 0 ] && break
let x+=n
done
echo 总和"$x"
函数
在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数
优点:
---使脚本代码更简洁,增强易读性
---提高shell脚本的执行效率
脚本中的函数应用
---适用于比较复杂的启动/终止控制操作
---方便在需要时多次调用
调用已定义的函数
---格式:函数名
---先定义了才能调用,就好比脚本的“内部命令”
函数传值
---格式:函数名 值1 值2
---传递的值作为函数的“位置参数”
一、函数的定义方法
1、格式1
function 函数名 {
命令序列
......
}
2、格式2
函数名() {
命令序列
......
}
将颜色输出的功能定义为函数
调用函数,可以自定义输出内容和颜色
脚本示例
1、从键盘循环取整数(0结束)并求和,输出最终结果
#!/bin/bash
num=0
while read -p read -p "请输入待累加的整数:(0结束)" n
do
[ $n -eq 0 ] && echo "输入非整数,相加结束" && break
sum=$[sum+n]
done
echo "总和是:${sum}"
2、跳过1~20以内非6的倍数,输出其它数的平方值
#!/bin/bash
n=0
while [ $n -ne 20 ]
do
let n++
[ $[n%6] -ne 0 ] && continue
echo $[n*n]
done
3、利用位置参数获取2个整数,计算出这两个整数的和
如果参数不够两个,则提示正确用法并退出脚本
#!/bin/bash
if [ $# -ne 2 ];then
echo "USE:$0 num1 num2"
exit
fi
expr $1 + $2