在编程中间,流程判断是很重要的一个步骤
分支结构
单分支结构
if 条件测试;then
命令序列
fi
双分支结构
if 条件测试;then
命令序列
else
命令序列
fi
多分支结构
if 条件测试;then
命令序列
elif 添加测试2;then
命令序列
elif 添加测试3;then
命令序列
else
命令序列
fi
在多分支结构的情况下面,一般使用的是case进行匹配
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
pattern3)
statement3
;;
……
*)
statementn
esac
case、in 和 esac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式。
- expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以。
- pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。
case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:
- 如果 expression 和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号
;;
才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。 - 如果 expression 没有匹配到任何一个模式,那么就执行
*)
后面的语句(*
表示其它所有值),直到遇见双分号;;
或者esac
才结束。*)
相当于多个 if 分支语句中最后的 else 部分。
对*)
的几点说明:
- Shell case in 语句中的
*)
用来“托底”,万一 expression 没有匹配到任何一个模式,*)
部分可以做一些“善后”工作,或者给用户一些提示。 - 可以没有
*)
部分。如果 expression 没有匹配到任何一个模式,那么就不执行任何操作。
除最后一个分支外(这个分支可以是普通分支,也可以是*)
分支),其它的每个分支都必须以;;
结尾,;;
代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;;
,也可以不写,因为无论如何,执行到 esac 都会结束整个 case in 语句。
case in 的 pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:
格式 | 说明 |
---|---|
* | 表示任意字符串。 |
[abc] | 表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。 |
[m-n] | 表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| | 表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 “abc” 或者 “xyz”。 |
如果不加以说明,Shell 的值都是字符串,expression 和 pattern 也是按照字符串的方式来匹配的;本节第一段代码看起来是判断数字是否相等,其实是判断字符串是否相等。
最后一个分支*)
并不是什么语法规定,它只是一个正则表达式,*
表示任意字符串,所以不管 expression 的值是什么,*)
总能匹配成功。
#if版本
#!/bin/bash
yum_server=192.168.110.1
os_version = `cat /etc/redhat-release | awk '{print $4}' |awk -F "." '{print $1","$2}'`
[ -d /etc/yum.repos.d ] || mkdir /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
if [ "$os_version"="7.3" ]:then
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
echo ""
elif [ "$os_version"="6.8" ];then
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
elif [ "$os_version"="5.3" ];then
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo
else
echo "error"
fi
case版本
#!/bin/bash
#yum config case
yum_server=192.168.110.1
os_version = `cat /etc/redhat-release | awk '{print $4}'`
[ -d /etc/yum.repos.d ] || mkdir /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
case $os_version in
7.3)
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
;;
6.8)
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
;;
*)
echo "error"
esac
判断条件
文件判断
[ -f file ] 测试文件是否为普通文件
[ -r file ] 当前用户对文件是否有读权限
[ -d file ] 测试指定路径是否为目录
[ -e file ] 测试文件是否存在
数值比较
判断的两边应该都是整数或者浮点数
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于
命令的间逻辑关系
逻辑与: &&
第一个条件为假时,第二条件不用再判断,最终结果已经有;
第一个条件为真时,第二条件必须得判断;
逻辑或: ||
#如果用户user6不存在,就添加用户user6
! id user6 && useradd user6
id user6 || useradd user6
数值的计算
echo "a*4" |bc
echo "scale=2;6/4" |bc 小数后面保存两位
awk 'BEGIN{print 1/2}'
echo "print 5.0/2 " |python
字符串比较
在 Shell 中进行字符串比较有专门的六个操作符,他们分别是:
=
:检测两个字符串是否相等,相等返回 true。!=
:检两个字符串是否相等,不相等返回 true。-z
:检测字符串长度是否为0,为 0 返回 true。-n
:检测字符串长度是否为0,不为 0 返回 true。str
:检测字符串是否为空,不为空返回 true。
要记得操作符左右两边都要加空格,否则会报语法错误。
这六个操作符可以进行字符串的非空比较,长度比较,相等比较等。
示例
硬盘警告
#!/bin/bash
disk_use = `df -Th | grep '/$' | awk '{print $(NF -1 )}'| awk -F "%" '{print $1}'`
mail_user = kaikai.wang
if [ $disk_use -ge 90 ];then
echo "`date +%F-%H` disk: ${disk_use}%" | mail -s "disk war.." $mail_user
fi
内存警告
#!bin/bash
mem_used=`free -m|grep '^Mem:' | awk '{print $3}'`
mem_total=`free -m|grep '^Mem:' | awk '{print $2}'`
mem_percent=$((mem_used*100/mem_total))
war_file=/tem/mem_war.txt
rm -rf $war_file
if [ $mem_percent -ge 80 ];then
echo "`date +%F-%H` memory:${mem_percent}%" > $war_file
fi
if [-f $war_file ];then
mail -s "mem war..." alice < $war_file
rm -rf $war_file
fi
用户比较
#!/bin/bash
read -p "Plaese input number:" num
read -p "Plaese input prefix:" prefix
for i in `seq $num`
do
user=$prefix$i
useradd $user
echo "123" |passwd --stdin $user
if [ $? -eq 0];then
echo "$user is created"
fi
done
升级版
#!/bin/bash
read -p "Plaese input number:" num
if [[ ! "$num" = ~^[0-9]+$ ]];then
echo "error number!"
exit
fi
read -p "Plaese input prefix:" prefix
if [-z "$prefix" ];then
echo "error prefix!"
exit
fi
for i in `seq $num`
do
user=$prefix$i
useradd $user
echo "123" |passwd --stdin $user $>/dev/null
if [ $? -eq 0];then
echo "$user is created"
fi
done
删除用户
#!/bin/bash
read -p "Pleade input a username: " user
id $user &>/dev/null
if [ $? -ne 0 ];then
echo "no such user: $user"
exit 1
fi
read -p "Are you sure?[y/n]: " action
if [ "$action" = "y" -o "$action" = "Y" -o "$action" = "YES" -o "$action" = "yes"] ;then
userdel -r $user
echo "$user is deleted"
else
echo "good!"
fi
安装apache
#!/bin/bash
#install apache
#v1.0 by kaikia.wang 2020/03/28
##################################
#判断网络
gateway=192.168.110.2
ping -c1 www.baidu.com &>/dev/null
if [ $? -eq 0 ];then
yum -y install httpd
systemctl start httpd
systemctl enable httpd
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
sed -ri '/^SELINUX=/cSELINUX=disable' /etc/seliunx/config
setenforce 0
curl http://127.0.0.1 &>/dev/null
if [ $? -eq 0 ];then
echo "Apache ok..."
fi
echo "Apache no ok..."
elif ping -c1 $gateway &>/dev/null;then
echo "check dns..."
else
echo "check ip address!"
fi